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
Hypolite Petovan 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
Hypolite Petovan a2afb101cd Fix off-by-one error in Message ID header count check in Util\Emailer 2022-06-25 05:35:24 -04:00
Tobias Diekershoff b9fe8ee38f
Merge pull request #11683 from MrPetovan/bug/fatal-errors
Fix a couple Fatal Errors
2022-06-25 11:20:33 +02:00
Hypolite Petovan 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
Hypolite Petovan 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
Hypolite Petovan 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
Hypolite Petovan 4cdc0ef267
Merge pull request #11680 from nupplaphil/feat/log_forward
Respect Forwarded-For headers
2022-06-24 10:12:19 -04:00
Roland Häder 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
Philipp Holzer 417b0072bb
Move documentation :-) 2022-06-23 23:24:15 +02:00
Philipp Holzer 2dc38e5632
Move documentation :-) 2022-06-23 23:23:36 +02:00
Philipp Holzer 5bf5b5e6c9
adaptions :-) 2022-06-23 23:01:09 +02:00
Philipp Holzer 12ba37e8d2
add more doc 2022-06-23 22:46:46 +02:00
Philipp Holzer 13783089e7
Add copyright 2022-06-23 22:44:17 +02:00
Philipp Holzer d441b90bda
Respect Forwarded-For headers 2022-06-23 22:42:35 +02:00
Hypolite Petovan dbc1ebbb5c
Merge pull request #11679 from Quix0r/rewrites/autotest
Rewrite of autotest.sh
2022-06-23 12:41:14 -04:00
Roland Häder 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
Hypolite Petovan 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
Roland Häder 657a8a7cb5
Changes:
- documented null value
- two ' to much!
2022-06-23 17:30:17 +02:00
Roland Häder 202857ba7d
No need to log $tid here 2022-06-23 17:30:17 +02:00
Roland Häder fd8f4269ff
Reformatted code 2022-06-23 17:30:17 +02:00
Roland Häder 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
Roland Häder a49fb9cbf9
Changes:
- added some type-hints
- added documentation
2022-06-23 17:30:16 +02:00
Roland Häder 84d3eecc33
Changes:
- added some type-hints
- changed double-quotes to single
2022-06-23 17:30:15 +02:00
Roland Häder 57e741f2cf
More type-hints added 2022-06-23 17:30:15 +02:00
Roland Häder 182c3db9b8
Changes:
- added type-hints
- added missing documentation
2022-06-23 17:30:15 +02:00
Roland Häder b8353a6eb7
Changes:
- reformatted some array
- added missing documentation
- added type-hints
- changed double-quotes to single
2022-06-23 17:30:14 +02:00
Roland Häder c6c936a80f
Added more type-hints 2022-06-23 17:30:14 +02:00
Roland Häder 3f74a59f73
Added some type-hints 2022-06-23 17:30:14 +02:00
Roland Häder 69a68be800
Added some missing type-hints 2022-06-23 17:30:13 +02:00
Roland Häder f889aeffb3
Changes:
- changed double-quotes to single
- added type-hints
2022-06-23 17:30:13 +02:00
Roland Häder d8ff966d21
Throw IAE again (should never become visible) 2022-06-23 17:30:13 +02:00
Roland Häder 35c78ce14c
Ops, cannot return Thread? 2022-06-23 17:30:12 +02:00
Roland Häder c2e26b4f49
Changed:
- Introduced InvalidArgumentException (should never come)
- added type-hints
2022-06-23 17:30:12 +02:00
Roland Häder 2f3705f471
Continued:
- renamed varibales to $camelCase
- added type-hints
- updated documentation
2022-06-23 17:30:11 +02:00
Hypolite Petovan 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
Roland Häder 0ddb315b23
$id in Transmitter::sendContactAccept() is a string, see Introduction class 2022-06-23 16:48:00 +02:00
Hypolite Petovan 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
Hypolite Petovan 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
Roland Häder 636fef26f1
Maybe this fixes missing array element 2022-06-23 07:40:49 +02:00
Roland Häder 589d0360a4
So simple ... Ops! 2022-06-23 04:58:45 +02:00
Roland Häder 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
Hypolite Petovan 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
Hypolite Petovan 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
Roland Häder 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
Roland Häder 15d8341d9a
Converted multiple single-comment (//) to multi-line comment block (/* */) 2022-06-22 18:06:35 +02:00
Roland Häder 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
Roland Häder 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
Hypolite Petovan 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
Roland Häder 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
Roland Häder 101cd2dd10
Changes:
- added some documentation
- fixed some documentation
- changed more double-quotes to singl
2022-06-22 16:14:14 +02:00
Roland Häder 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
Roland Häder ee8d0ad619
Changes:
- added more type-hints
- added some documentation
2022-06-22 14:36:47 +02:00
Roland Häder feec96cbc4
Return empty array on error (I hope it works this way). 2022-06-22 14:36:47 +02:00
Roland Häder 2dd7d465e8
Changes:
- added more type-hints
- updated documentation
- changed double-quotes to single
2022-06-22 14:36:47 +02:00
Roland Häder 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
Roland Häder 12add2fb64
$data can turn into bool here 2022-06-22 14:36:46 +02:00
Roland Häder 08f55f0358
Ops, forgot to rename these, too. 2022-06-22 14:36:46 +02:00
Roland Häder 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
Roland Häder dfa95ea58d
Changes:
- added type-hints
- added documentation
2022-06-22 14:36:45 +02:00
Roland Häder 84bfc37bf1
Changes:
- added more type-hints
- added missing documentation
2022-06-22 14:36:45 +02:00
Tobias Diekershoff 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
Hypolite Petovan 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
Hypolite Petovan 7295138f8d Remove type-hint inconsistent with expected return value in Database->getVariable 2022-06-22 07:47:15 -04:00
Hypolite Petovan d68f307337 Remove email subject encoding from ItemCCEmail constructor
- It was wrongly re-encoded in Emailer::send
2022-06-21 21:12:09 -04:00
Hypolite Petovan 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
Roland Häder 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
Roland Häder 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
Hypolite Petovan 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
Roland Häder 8092188991
Added important comment from @nupplaphil@github.com 2022-06-21 21:12:59 +02:00
Roland Häder 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
Roland Häder 80c8ec17c2
Fixed documentation 2022-06-21 18:43:25 +02:00
Roland Häder 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
Roland Häder 3b8d9a7248
Use protected $this->logger instead 2022-06-21 17:54:48 +02:00
Roland Häder 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
Roland Häder dcedd2e5d9
Ops, WWORD ... 2022-06-21 13:54:03 +02:00
Roland Häder 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
Roland Häder 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
Roland Häder a7651fa1d5
Changes:
- let's at least log the error message, yes it does flood your logfile
2022-06-21 13:47:40 +02:00
Roland Häder 1080a840f5
Changes:
- Database->$driver can no longer be NULL, an empty string is fine anyway
2022-06-21 13:47:39 +02:00
Roland Häder 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
Roland Häder 0d81a08e3c
WIP: Properly some fixes? Also why is DROP VIEW IF EXISTS is being killed? 2022-06-21 13:47:39 +02:00
Roland Häder 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
Roland Häder f62c28008a
Removed comment 2022-06-21 13:47:38 +02:00
Roland Häder cefffde691
Changes:
- added type-hints
- added some missing documentation
2022-06-21 13:47:37 +02:00
Roland Häder f1867463a0
Changes:
- added more type-hints
2022-06-21 13:47:37 +02:00
Roland Häder 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
Hypolite Petovan e6ddb167f6
Merge pull request #11664 from tobiasd/20220621-fr
update FR translations THX kalon33
2022-06-21 07:43:12 -04:00
Tobias Diekershoff 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
Tobias Diekershoff fff6e30782
update FR translations THX kalon33 2022-06-21 06:45:14 +02:00
Hypolite Petovan 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
Roland Häder 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
Roland Häder 95f9eb34ac
Fixed indenting 2022-06-21 01:29:33 +02:00
Hypolite Petovan ee9bc338a5
Merge pull request #11663 from Quix0r/composer/upgrade
Updated composer.phar
2022-06-20 19:17:13 -04:00
Roland Häder 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
Roland Häder 6a98ffa330
Updated composer.phar 2022-06-20 22:55:21 +02:00
Roland Häder 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
Roland Häder ea22e88896
Added documentation 2022-06-20 21:02:34 +02:00
Roland Häder 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
Hypolite Petovan 88eacbf66e Ensure parameter 4 of Post\Media::splitAttachment is a boolean value 2022-06-20 14:34:02 -04:00
Roland Häder 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
Roland Häder feb87e8dc3
Changes:
- let's start throwing exceptions on e.g. invalid arguments instead of returning
  FALSE
2022-06-20 19:09:08 +02:00
Roland Häder 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
Roland Häder 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
Roland Häder e5cc7a5ab1
Fixes:
- Strings::isHex() should not be misused for checking on NULL
2022-06-20 08:25:45 +02:00
Roland Häder 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
Roland Häder 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
Roland Häder 9c80dd35e5
Both declarations must be the same 2022-06-20 08:07:12 +02:00
Tobias Diekershoff 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
Roland Häder cd3b01fd82
Changed:
- cannot have type-hints :-(
2022-06-20 03:48:34 +02:00
Roland Häder 94a594eeb2
Ops, wrong type-hint 2022-06-20 03:36:36 +02:00
Roland Häder ec96f2252e
Changes:
- added type-hints
- added some missing documentation
2022-06-20 03:10:23 +02:00
Roland Häder 14bf72e4fe
Changes:
- added some documentation
- added type-hints
2022-06-20 02:48:05 +02:00
Roland Häder 97904ea7dd
Changes:
- added type-hints
- added missing documentation
2022-06-20 02:48:02 +02:00
Roland Häder a0c8fc6d6e
Changes:
- added more type-hints
2022-06-20 02:48:02 +02:00
Hypolite Petovan 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
Hypolite Petovan 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
Roland Häder d276f2c62b
Changes:
- added type-hints
- changed some double-quotes to single
2022-06-20 01:00:29 +02:00
Roland Häder 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
Roland Häder 2512449751
Incremented again 2022-06-19 15:36:16 +02:00
Roland Häder 9f24a4b60e
Fixed documentation/SQL dump with ./bin/console dbstructure dump 2022-06-19 15:36:16 +02:00
Roland Häder 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
Hypolite Petovan 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
Roland Häder 5a553df7d8
Incremented database version 2022-06-19 14:41:36 +02:00
Roland Häder ed3c53a5f8
Ops, not here wanted. :-( 2022-06-19 14:06:32 +02:00
Roland Häder bff57bb030
Changes:
- added type-hints
- added returned type-hints in interface (I checked all)
2022-06-19 14:00:31 +02:00
Hypolite Petovan 777872e6fa
Merge pull request #11658 from tobiasd/20220619-accesskey
Accesskey was used twice
2022-06-19 07:09:20 -04:00
Roland Häder c0d7f8944d
Some calls saved 2022-06-19 11:26:10 +02:00
Roland Häder 60f8c2d795
Changes:
- added missing type-hints
- added documentation for a method
2022-06-19 10:50:09 +02:00
Roland Häder 5f6943b008
Changes:
- MySQL index on BLOB/TEXT can only be partial (e.g.: `column`(length))
2022-06-19 10:50:06 +02:00
Roland Häder 5792a01a01
Contact::getAccountType()'s parameter is never a string, ops 2022-06-19 09:36:24 +02:00
Roland Häder f3599fa3e9
Changes:
- dbstructure(null) is no longer possible, an empty string does it
2022-06-19 09:13:10 +02:00
Tobias Diekershoff 065dad79ca
updated the Accesskey documentation accordingly 2022-06-19 06:33:21 +02:00
Tobias Diekershoff 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
Roland Häder b6bfe72083
Wrong returned type, has to be array 2022-06-19 02:40:07 +02:00
Roland Häder 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
Roland Häder 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
Roland Häder d7d2ad77ff
Ops, also this! 2022-06-18 23:31:52 +02:00
Roland Häder 39f2d197ea
Changed to suggestings (back to original) + fixed typo in scalar type 2022-06-18 23:30:37 +02:00
Roland Häder 6f1d52cf71
Changed back to suggestions by @MrPetovan 2022-06-18 23:24:08 +02:00
Roland Häder 2f961b11bf
Naming-convention:
- variables should start lower-case: $image
2022-06-18 23:16:34 +02:00
Roland Häder fa14a02a19
Changes:
- added type-hints
- added documentation
- changed double-quotes to single
2022-06-18 23:12:52 +02:00
Roland Häder f3b57008b5
Proper type is string 2022-06-18 18:41:16 +02:00
Roland Häder 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
Roland Häder 9691bb06fb
Changes:
- added more type-hints
- added missing documentation
2022-06-18 18:21:29 +02:00
Roland Häder 94eb426151
Nodeinfo::getOrganization() doesn't need configuration object being inserted
when you have DI::config() around.
2022-06-18 17:56:33 +02:00
Roland Häder c29c49797a
Added missing type-hints 2022-06-18 17:52:46 +02:00
Roland Häder 4e437190c5
Renamed variable, no need for "orig_" prefix 2022-06-18 17:50:11 +02:00
Roland Häder 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
Roland Häder 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
Roland Häder 8ba3f13fae
Changes:
- added more type-hints
- added missing documentation
2022-06-18 17:09:46 +02:00
Roland Häder 7ec07178c8
Changes:
- added missing type-hints
- added missing documentation
2022-06-18 16:59:23 +02:00
Hypolite Petovan e90ad0c1cd
Merge pull request #11653 from Quix0r/fixes/more-type-hints
More type-hints added
2022-06-18 10:33:33 -04:00
Hypolite Petovan 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
Roland Häder 92a1d14e5e
Updated documentation and SQL dump, according to woodpecker tests 2022-06-18 16:02:33 +02:00
Roland Häder 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
Roland Häder 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
Roland Häder 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
Roland Häder 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
Roland Häder 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
Roland Häder 89302d0843
Some outside code relies on returned "false" 2022-06-18 05:06:18 +02:00
Roland Häder aaf5c323b6
Fixed indenting 2022-06-18 05:04:14 +02:00
Roland Häder 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
Roland Häder 51f43278d6
Fixed incompatible types 2022-06-17 18:00:36 +02:00
Roland Häder 88c40f3336 Ops, wrong type again 2022-06-17 17:18:31 +02:00
Roland Häder a770634b95 Ops, wrong type 2022-06-17 17:18:31 +02:00
Roland Häder 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
Roland Häder c467bff79f Some more type-hints added 2022-06-17 17:18:31 +02:00
Roland Häder 4f3321cc9f Nore fixes 2022-06-17 17:18:31 +02:00
Roland Häder 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
Roland Häder 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
Roland Häder 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
Roland Häder 0c9aff8a09 Also need to declare $profile or otherwise an invocation of
Receiver::getReceiverForActor() will fail.
2022-06-17 17:18:31 +02:00
Roland Häder af8cd5ca86 Worker::getWaitingJobForPID() can also return FALSE on failure ... :-( 2022-06-17 17:18:31 +02:00
Roland Häder 227bab43a8 Ops, wrong type-hint here, must be string ($nickname can never be an integer). 2022-06-17 17:18:31 +02:00
Roland Häder f7c1eaa858 Continued:
- added type-hints
- removed out-dated documentation
- added some missing documentation
2022-06-17 17:18:31 +02:00
Roland Häder 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
Roland Häder 45b5f67bca Fix for non-existing record system.mobile_theme in config table 2022-06-17 17:18:31 +02:00
Roland Häder 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
Roland Häder 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
Roland Häder 4e53666c70 Added more type-hints 2022-06-17 17:18:31 +02:00
Roland Häder 7560dccc08 Added again more type-hints 2022-06-17 17:18:31 +02:00
Roland Häder 2766c7d9cf Continued:
- added more type-hints
- added some missing documentation
2022-06-17 17:18:31 +02:00
Roland Häder a587217f47 Fixed "Argument 4 passed to Friendica\Protocol\DFRN::processVerbs() must be of the type bool" 2022-06-17 17:18:31 +02:00
Roland Häder 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
Roland Häder c351099c5a Ops, bad type-hint here 2022-06-17 17:18:31 +02:00
Roland Häder 2c5595c358 Another incompatible method declaration fixed + type-hints added 2022-06-17 17:18:31 +02:00
Roland Häder 40d7f29a11 Continued:
- more type-hints
- fixed incompatible method declarations
2022-06-17 17:18:31 +02:00
Roland Häder 1edc6b3c3b Added more type-hints for "App" classes 2022-06-17 17:18:31 +02:00
Roland Häder 42b04f397b Added more type-hints 2022-06-17 17:18:31 +02:00
Roland Häder aa5f0d5ec1 Added more type-hints and documented a few methods 2022-06-17 17:18:31 +02:00
Roland Häder 97e27cb523 Added more type-hints 2022-06-17 17:18:31 +02:00
Roland Häder c2e889cfae Added more type-hints 2022-06-17 17:18:31 +02:00
Hypolite Petovan 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
Roland Häder 5106bb2881
Added parenthesis 2022-06-17 09:41:11 +02:00
Roland Häder a903dbd77e
Wrong braces causing 'undefined index causer-id'. See #11632 2022-06-16 23:00:16 +02:00
Hypolite Petovan 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
Roland Häder 6035de6883
Continued:
- added more type-hints
- also cannot return FALSE when array is set
2022-06-16 19:06:41 +02:00
Hypolite Petovan 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
Roland Häder 51a7b5c584
Made also this one sweeter (null-coalscing) 2022-06-16 17:36:47 +02:00
Roland Häder 0e1f734b03
Also make this null-coalscing 2022-06-16 17:35:01 +02:00
Roland Häder e8fee5644b
Ops, syntax errors get unnoticed with a simple editor. :-( 2022-06-16 17:10:02 +02:00
Roland Häder 624e4c192c
Changed to null-coalscing style (??) as sugguested by @MrPetovan 2022-06-16 16:59:54 +02:00
Roland Häder 962b06bf41
Added check as suggested by @MrPetovan for empty $message. 2022-06-16 16:54:51 +02:00
Roland Häder 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
Roland Häder 7814ba4fc4
Fixes for bad invocations of HTML::toBBCode() (1st parameter is now string) 2022-06-16 16:54:50 +02:00
Roland Häder 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
Roland Häder 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
Hypolite Petovan 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
Roland Häder e9af4b5bb9
Shorter code, thanks to @annando pointing this out 2022-06-16 13:29:30 +02:00
Roland Häder 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
Tobias Diekershoff 13ef86d4a3
Merge pull request #11644 from Quix0r/fixes/file-permissions
Fixed file permissions
2022-06-16 10:02:31 +02:00
Roland Häder 58c48977ec
These files should never have executable files 2022-06-16 09:14:23 +02:00
Roland Häder fd0d4aedee
Font files should NEVER be executable
Signed-off-by: Roland Häder <roland@mxchange.org>
2022-06-16 09:13:48 +02:00
Hypolite Petovan 207bf58801
Merge pull request #11624 from Quix0r/fixes/type-hints
Added more known type-hints
2022-06-15 16:32:25 -04:00
Roland Häder 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
Roland Häder 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
Roland Häder 34aee64349
Added more type-hints
Signed-off-by: Roland Häder <roland@mxchange.org>
2022-06-15 21:52:51 +02:00
Roland Häder 143e4c4a18
Added more known type-hints
Signed-off-by: Roland Häder <roland@mxchange.org>
2022-06-15 21:52:50 +02:00
Tobias Diekershoff 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
Michael 726c4dff7d You can now store the avatar in a separate folder and host 2022-06-15 03:59:26 +00:00
Hypolite Petovan f839cd3826
Merge pull request #11642 from annando/platform-default
Some more default avatars
2022-06-13 16:31:34 -04:00
Michael 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
Tobias Diekershoff 6d6f356446
AR translation updates THX ButterflyOfFire 2022-06-13 14:27:14 +02:00
Tobias Diekershoff 7614ace843
added HU translation THX Balázs Úr 2022-06-13 14:27:14 +02:00
Tobias Diekershoff cc77052817
update FR translations THX kalon33 2022-06-13 14:27:06 +02:00
Hypolite Petovan 663296b107
Merge pull request #11639 from annando/platform-default
Use platform specific default avatar pictures
2022-06-13 07:59:49 -04:00
Michael 70b9a8114d Improve license comment 2022-06-13 10:30:21 +00:00
Michael d9fb081db9 Using separate avatars for different peertube account types 2022-06-13 10:27:46 +00:00
Michael a47f1efec3 use correct image for Pleroma 2022-06-13 10:18:17 +00:00
Michael c1a64b77c0 Improved license text 2022-06-13 10:03:34 +00:00
Michael a5b5f9316d Updated database.sql and messages.po 2022-06-13 05:46:37 +00:00
Michael e0a0c57c44 Use platform specific default avatar pictures 2022-06-13 05:18:54 +00:00
Tobias Diekershoff 05a76a3dc2
initial CHANGELOG for the 2022.09 release 2022-06-11 10:07:04 +02:00
Tobias Diekershoff 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
/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)
Friendica Core
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)
# - XDEBUG_CONFIG= ... Set some XDEBUG specific environment settings for development
DATABASENAME=${MYSQL_DATABASE:-test}
DATABASEUSER=${MYSQL_USERNAME:-friendica}
DATABASEHOST=${MYSQL_HOST:-localhost}
BASEDIR=$PWD
DATABASE_NAME=${FRIENDICA_MYSQL_DATABASE:-test}
DATABASE_USER=${FRIENDICA_MYSQL_USERNAME:-friendica}
DATABASE_HOST=${FRIENDICA_MYSQL_HOST:-localhost}
DATABASE_PASSWORD=${FRIENDICA_MYSQL_PASSWORD:-friendica}
BASEDIR=${PWD}
DBCONFIGS="mysql mariadb"
TESTS="REDIS MEMCACHE MEMCACHED APCU NODB"
export MYSQL_DATABASE="$DATABASENAME"
export MYSQL_USERNAME="$DATABASEUSER"
export MYSQL_PASSWORD="friendica"
export MYSQL_DATABASE="${DATABASE_NAME}"
export MYSQL_USERNAME="${DATABASE_USER}"
export MYSQL_PASSWORD="${DATABASE_PASSWORD}"
if [ -z "$PHP_EXE" ]; then
if [ -z "${PHP_EXE}" ]; then
PHP_EXE=php
fi
PHP=$(which "$PHP_EXE")
PHP=$(which "${PHP_EXE}")
# Use the Friendica internal composer
COMPOSER="$BASEDIR/bin/composer.phar"
COMPOSER="${BASEDIR}/bin/composer.phar"
set -e
_XDEBUG_CONFIG=$XDEBUG_CONFIG
_XDEBUG_CONFIG=${XDEBUG_CONFIG}
unset XDEBUG_CONFIG
function show_syntax() {
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 "\nDatabase environment variables:\n" >&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
}
if [ -x "$PHP" ]; then
echo "Using PHP executable $PHP"
if [ -x "${PHP}" ]; then
echo "Using PHP executable ${PHP}"
else
echo "Could not find PHP executable $PHP_EXE" >&2
echo "Could not find PHP executable ${PHP_EXE}" >&2
exit 3
fi
echo "Installing depdendencies"
$PHP "$COMPOSER" install
${PHP} "$COMPOSER" install
PHPUNIT="$BASEDIR/vendor/bin/phpunit"
PHPUNIT="${BASEDIR}/vendor/bin/phpunit"
if [ -x "$PHPUNIT" ]; then
echo "Using PHPUnit executable $PHPUNIT"
if [ -x "${PHPUNIT}" ]; then
echo "Using PHPUnit executable ${PHPUNIT}"
else
echo "Could not find PHPUnit executable after composer $PHPUNIT" >&2
echo "Could not find PHPUnit executable after composer ${PHPUNIT}" >&2
exit 3
fi
@ -83,8 +84,8 @@ fi
if [ "$1" ]; then
FOUND=0
for DBCONFIG in $DBCONFIGS; do
if [ "$1" = "$DBCONFIG" ]; then
for DBCONFIG in ${DBCONFIGS}; do
if [ "$1" = "${DBCONFIG}" ]; then
FOUND=1
break
fi
@ -103,13 +104,13 @@ fi
function cleanup_config() {
if [ -n "$DOCKER_CONTAINER_ID" ]; then
echo "Kill the docker $DOCKER_CONTAINER_ID"
docker stop "$DOCKER_CONTAINER_ID"
docker rm -f "$DOCKER_CONTAINER_ID"
if [ -n "${DOCKER_CONTAINER_ID}" ]; then
echo "Kill the docker ${DOCKER_CONTAINER_ID}"
docker stop "${DOCKER_CONTAINER_ID}"
docker rm -f "${DOCKER_CONTAINER_ID}"
fi
cd "$BASEDIR"
cd "${BASEDIR}"
# Restore existing config
if [ -f config/local.config-autotest-backup.php ]; then
@ -122,77 +123,77 @@ trap cleanup_config EXIT
function execute_tests() {
DB=$1
echo "Setup environment for $DB testing ..."
echo "Setup environment for ${DB} testing ..."
# back to root folder
cd "$BASEDIR"
cd "${BASEDIR}"
# backup current config
if [ -f config/local.config.php ]; then
mv config/local.config.php config/local.config-autotest-backup.php
fi
if [ -z "$NOINSTALL" ]; then
if [ -z "${NOINSTALL}" ]; then
#drop database
if [ "$DB" == "mysql" ]; then
if [ -n "$USEDOCKER" ]; then
if [ "${DB}" == "mysql" ]; then
if [ -n "${USEDOCKER}" ]; then
echo "Fire up the mysql docker"
DOCKER_CONTAINER_ID=$(docker run \
-e MYSQL_ROOT_PASSWORD=friendica \
-e MYSQL_USER="$DATABASEUSER" \
-e MYSQL_USER="${DATABASE_USER}" \
-e MYSQL_PASSWORD=friendica \
-e MYSQL_DATABASE="$DATABASENAME" \
-e MYSQL_DATABASE="${DATABASE_NAME}" \
-d mysql)
DATABASEHOST=$(docker inspect --format="{{.NetworkSettings.IPAddress}}" "$DOCKER_CONTAINER_ID")
DATABASE_HOST=$(docker inspect --format="{{.NetworkSettings.IPAddress}}" "${DOCKER_CONTAINER_ID}")
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
echo "Your mysql binary is not provided by mysql"
echo "To use the docker container set the USEDOCKER environment variable"
exit 3
fi
mysql -u "$DATABASEUSER" -pfriendica -e "DROP DATABASE IF EXISTS $DATABASENAME" -h $DATABASEHOST || 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 "DROP DATABASE IF EXISTS ${DATABASE_NAME}" -h ${DATABASE_HOST} || true
mysql -u "${DATABASE_USER}" -pfriendica -e "CREATE DATABASE ${DATABASE_NAME} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci" -h ${DATABASE_HOST}
else
DATABASEHOST=mysql
DATABASE_HOST=mysql
fi
fi
echo "Waiting for MySQL $DATABASEHOST initialization..."
if ! bin/wait-for-connection $DATABASEHOST 3306 300; then
echo "Waiting for MySQL ${DATABASE_HOST} initialization..."
if ! bin/wait-for-connection ${DATABASE_HOST} 3306 300; then
echo "[ERROR] Waited 300 seconds, no response" >&2
exit 1
fi
echo "MySQL is up."
fi
if [ "$DB" == "mariadb" ]; then
if [ -n "$USEDOCKER" ]; then
if [ "${DB}" == "mariadb" ]; then
if [ -n "${USEDOCKER}" ]; then
echo "Fire up the mariadb docker"
DOCKER_CONTAINER_ID=$(docker run \
-e MYSQL_ROOT_PASSWORD=friendica \
-e MYSQL_USER="$DATABASEUSER" \
-e MYSQL_USER="${DATABASE_USER}" \
-e MYSQL_PASSWORD=friendica \
-e MYSQL_DATABASE="$DATABASENAME" \
-e MYSQL_DATABASE="${DATABASE_NAME}" \
-d mariadb)
DATABASEHOST=$(docker inspect --format="{{.NetworkSettings.IPAddress}}" "$DOCKER_CONTAINER_ID")
DATABASE_HOST=$(docker inspect --format="{{.NetworkSettings.IPAddress}}" "${DOCKER_CONTAINER_ID}")
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
echo "Your mysql binary is not provided by mysql"
echo "To use the docker container set the USEDOCKER environment variable"
exit 3
fi
mysql -u "$DATABASEUSER" -pfriendica -e "DROP DATABASE IF EXISTS $DATABASENAME" -h $DATABASEHOST || 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 "DROP DATABASE IF EXISTS ${DATABASE_NAME}" -h ${DATABASE_HOST} || true
mysql -u "${DATABASE_USER}" -pfriendica -e "CREATE DATABASE ${DATABASE_NAME} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci" -h ${DATABASE_HOST}
else
DATABASEHOST=mariadb
DATABASE_HOST=mariadb
fi
fi
echo "Waiting for MariaDB $DATABASEHOST initialization..."
if ! bin/wait-for-connection $DATABASEHOST 3306 300; then
echo "Waiting for MariaDB ${DATABASE_HOST} initialization..."
if ! bin/wait-for-connection ${DATABASE_HOST} 3306 300; then
echo "[ERROR] Waited 300 seconds, no response" >&2
exit 1
fi
@ -200,28 +201,28 @@ function execute_tests() {
echo "MariaDB is up."
fi
if [ -n "$USEDOCKER" ]; then
if [ -n "${USEDOCKER}" ]; then
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
export MYSQL_HOST="$DATABASEHOST"
export MYSQL_HOST="${DATABASE_HOST}"
#call installer
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
#test execution
echo "Testing..."
rm -fr "coverage-html"
mkdir "coverage-html"
if [[ "$_XDEBUG_CONFIG" ]]; then
export XDEBUG_CONFIG=$_XDEBUG_CONFIG
if [[ "${_XDEBUG_CONFIG}" ]]; then
export XDEBUG_CONFIG=${_XDEBUG_CONFIG}
fi
COVER=''
if [ -z "$NOCOVERAGE" ]; then
if [ -z "${NOCOVERAGE}" ]; then
COVER="--coverage-clover tests/autotest-clover.xml"
else
echo "No coverage"
@ -229,51 +230,51 @@ function execute_tests() {
# per default, there is no cache installed
GROUP='--exclude-group REDIS,MEMCACHE,MEMCACHED,APCU'
if [ "$TEST_SELECTION" == "REDIS" ]; then
if [ "${TEST_SELECTION}" == "REDIS" ]; then
GROUP="--group REDIS"
fi
if [ "$TEST_SELECTION" == "MEMCACHE" ]; then
if [ "${TEST_SELECTION}" == "MEMCACHE" ]; then
GROUP="--group MEMCACHE"
fi
if [ "$TEST_SELECTION" == "MEMCACHED" ]; then
if [ "${TEST_SELECTION}" == "MEMCACHED" ]; then
GROUP="--group MEMCACHED"
fi
if [ "$TEST_SELECTION" == "APCU" ]; then
if [ "${TEST_SELECTION}" == "APCU" ]; then
GROUP="--group APCU"
fi
if [ "$TEST_SELECTION" == "NODB" ]; then
if [ "${TEST_SELECTION}" == "NODB" ]; then
GROUP="--exclude-group DB,SLOWDB"
fi
INPUT="$BASEDIR/tests"
INPUT="${BASEDIR}/tests"
if [ -n "$2" ]; then
INPUT="$INPUT/$2"
INPUT="${INPUT}/$2"
fi
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"
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"
RESULT=$?
if [ -n "$DOCKER_CONTAINER_ID" ]; then
echo "Kill the docker $DOCKER_CONTAINER_ID"
docker stop $DOCKER_CONTAINER_ID
docker rm -f $DOCKER_CONTAINER_ID
unset $DOCKER_CONTAINER_ID
if [ -n "${DOCKER_CONTAINER_ID}" ]; then
echo "Kill the docker ${DOCKER_CONTAINER_ID}"
docker stop ${DOCKER_CONTAINER_ID}
docker rm -f ${DOCKER_CONTAINER_ID}
unset ${DOCKER_CONTAINER_ID}
fi
}
#
# Start the test execution
#
if [ -z "$1" ] && [ -n "$TEST_SELECTION" ]; then
if [ -z "$1" ] && [ -n "${TEST_SELECTION}" ]; then
# run all known database configs
for DBCONFIG in $DBCONFIGS; do
execute_tests "$DBCONFIG"
for DBCONFIG in ${DBCONFIGS}; do
execute_tests "${DBCONFIG}"
done
else
FILENAME="$2"
if [ -n "$2" ] && [ ! -f "tests/$FILENAME" ] && [ "${FILENAME:0:2}" != "--" ]; then
FILENAME="../$FILENAME"
if [ -n "$2" ] && [ ! -f "tests/${FILENAME}" ] && [ "${FILENAME:0:2}" != "--" ]; then
FILENAME="../${FILENAME}"
fi
execute_tests "$1" "$FILENAME" "$3"
execute_tests "$1" "${FILENAME}" "$3"
fi

View file

@ -31,7 +31,7 @@ use Friendica\Model\Contact;
define('FRIENDICA_PLATFORM', 'Friendica');
define('FRIENDICA_CODENAME', 'Giant Rhubarb');
define('FRIENDICA_VERSION', '2022.06');
define('FRIENDICA_VERSION', '2022.09-dev');
define('DFRN_PROTOCOL_VERSION', '2.23');
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
if (!defined("SIGTERM")) {
define("SIGTERM", 15);
if (!defined('SIGTERM')) {
define('SIGTERM', 15);
}
/**
@ -117,6 +117,7 @@ function local_user()
if (!empty($_SESSION['authenticated']) && !empty($_SESSION['uid'])) {
return intval($_SESSION['uid']);
}
return false;
}
@ -169,7 +170,7 @@ function remote_user()
*
* @param string $s - Text of notice
*/
function notice($s)
function notice(string $s)
{
if (empty($_SESSION)) {
return;
@ -189,7 +190,7 @@ function notice($s)
*
* @param string $s - Text of notice
*/
function info($s)
function info(string $s)
{
if (empty($_SESSION)) {
return;

204
composer.lock generated
View file

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

View file

@ -1,6 +1,6 @@
-- ------------------------------------------
-- Friendica 2022.06 (Giant Rhubarb)
-- DB_UPDATE_VERSION 1469
-- Friendica 2022.09-dev (Giant Rhubarb)
-- DB_UPDATE_VERSION 1472
-- ------------------------------------------
@ -1216,13 +1216,13 @@ CREATE TABLE IF NOT EXISTS `post-link` (
CREATE TABLE IF NOT EXISTS `post-media` (
`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',
`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',
`mimetype` varchar(60) COMMENT '',
`height` smallint unsigned COMMENT 'Height of the media',
`width` smallint unsigned COMMENT 'Width of the media',
`size` int unsigned COMMENT 'Media size',
`preview` varbinary(255) COMMENT 'Preview URL',
`size` bigint unsigned COMMENT 'Media size',
`preview` varbinary(512) COMMENT 'Preview URL',
`preview-height` smallint unsigned COMMENT 'Height of the preview picture',
`preview-width` smallint unsigned COMMENT 'Width of the preview picture',
`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-image` varbinary(255) COMMENT 'Image of the publisher of the media',
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`),
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Attached media';

View file

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

View file

@ -10,13 +10,13 @@ Fields
| --------------- | --------------------------------------------------------- | ----------------- | ---- | --- | ------- | -------------- |
| 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 | |
| url | Media URL | varbinary(511) | NO | | NULL | |
| url | Media URL | varbinary(1024) | NO | | NULL | |
| type | Media type | tinyint unsigned | NO | | 0 | |
| mimetype | | varchar(60) | YES | | NULL | |
| height | Height of the media | smallint unsigned | YES | | NULL | |
| width | Width of the media | smallint unsigned | YES | | NULL | |
| size | Media size | int unsigned | YES | | NULL | |
| preview | Preview URL | varbinary(255) | YES | | NULL | |
| size | Media size | bigint unsigned | YES | | NULL | |
| preview | Preview URL | varbinary(512) | YES | | NULL | |
| preview-height | Height of the preview picture | smallint unsigned | YES | | NULL | |
| preview-width | Width of the preview picture | smallint unsigned | YES | | NULL | |
| description | | text | YES | | NULL | |
@ -31,11 +31,11 @@ Fields
Indexes
------------
| Name | Fields |
| ---------- | ------------------- |
| PRIMARY | id |
| uri-id-url | UNIQUE, uri-id, url |
| uri-id-id | uri-id, id |
| Name | Fields |
| ---------- | ------------------------ |
| PRIMARY | id |
| uri-id-url | UNIQUE, uri-id, url(512) |
| uri-id-id | uri-id, id |
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
$theme = Strings::sanitizeFilePathItem($_GET['theme'] ?? null);
$theme = Strings::sanitizeFilePathItem($_GET['theme'] ?? '');
if ($theme && is_file("view/theme/$theme/config.php")) {
$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 (!Strings::isHex(DI::args()->getArgv()[3])) {
if (!Strings::isHex(DI::args()->getArgv()[3] ?? '')) {
DI::baseUrl()->redirect('photos/' . $user['nickname'] . '/album');
}
$album = hex2bin(DI::args()->getArgv()[3]);
@ -892,7 +892,7 @@ function photos_content(App $a)
return;
}
$selname = Strings::isHex($datum) ? hex2bin($datum) : '';
$selname = (!is_null($datum) && Strings::isHex($datum)) ? hex2bin($datum) : '';
$albumselect = '';
@ -954,7 +954,7 @@ function photos_content(App $a)
// Display a single photo album
if ($datatype === 'album') {
// 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');
}
$album = hex2bin($datum);

View file

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

View file

@ -145,7 +145,7 @@ class App
$this->nickname = $nickname;
}
public function isLoggedIn()
public function isLoggedIn(): bool
{
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
*/
public function isSiteAdmin()
public function isSiteAdmin(): bool
{
$admin_email = $this->config->get('config', 'admin_email');
@ -166,18 +166,18 @@ class App
/**
* Fetch the user id
* @return int
* @return int User id
*/
public function getLoggedInUserId()
public function getLoggedInUserId(): int
{
return $this->user_id;
}
/**
* Fetch the user nick name
* @return string
* @return string User's nickname
*/
public function getLoggedInUserNickname()
public function getLoggedInUserNickname(): string
{
return $this->nickname;
}
@ -198,7 +198,7 @@ class App
*
* @return int
*/
public function getProfileOwner():int
public function getProfileOwner(): int
{
return $this->profile_owner;
}
@ -219,7 +219,7 @@ class App
*
* @return int
*/
public function getContactId():int
public function getContactId(): int
{
return $this->contact_id;
}
@ -241,7 +241,7 @@ class App
*
* @return int
*/
public function getTimeZone():string
public function getTimeZone(): string
{
return $this->timezone;
}
@ -260,9 +260,9 @@ class App
/**
* Fetch workerqueue information
*
* @return array
* @return array Worker queue
*/
public function getQueue()
public function getQueue(): array
{
return $this->queue ?? [];
}
@ -270,8 +270,8 @@ class App
/**
* Fetch a specific workerqueue field
*
* @param string $index
* @return mixed
* @param string $index Work queue record to fetch
* @return mixed Work queue item or NULL if not found
*/
public function getQueueValue(string $index)
{
@ -306,9 +306,9 @@ class 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)
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.
*
* @return string
* @return string Current theme name or empty string in installation phase
* @throws Exception
*/
public function getCurrentTheme()
public function getCurrentTheme(): string
{
if ($this->mode->isInstall()) {
return '';
@ -425,10 +425,10 @@ class App
/**
* Returns the current mobile theme name.
*
* @return string
* @return string Mobile theme name or empty string if installer
* @throws Exception
*/
public function getCurrentMobileTheme()
public function getCurrentMobileTheme(): string
{
if ($this->mode->isInstall()) {
return '';
@ -441,12 +441,22 @@ class App
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;
}
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;
}
@ -525,10 +535,10 @@ class App
/**
* 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
*/
public function getCurrentThemeStylesheetPath()
public function getCurrentThemeStylesheetPath(): string
{
return Core\Theme::getStylesheetPath($this->getCurrentTheme());
}
@ -730,7 +740,7 @@ class App
*
* @throws HTTPException\InternalServerErrorException
*/
public function redirect($toUrl)
public function redirect(string $toUrl)
{
if (!empty(parse_url($toUrl, PHP_URL_SCHEME))) {
Core\System::externalRedirect($toUrl);

View file

@ -78,7 +78,7 @@ class Arguments
/**
* @return string The whole command of this call
*/
public function getCommand()
public function getCommand(): string
{
return $this->command;
}
@ -94,7 +94,7 @@ class Arguments
/**
* @return array All arguments of this call
*/
public function getArgv()
public function getArgv(): array
{
return $this->argv;
}
@ -102,7 +102,7 @@ class Arguments
/**
* @return string The used HTTP method
*/
public function getMethod()
public function getMethod(): string
{
return $this->method;
}
@ -110,7 +110,7 @@ class Arguments
/**
* @return int The count of arguments of this call
*/
public function getArgc()
public function getArgc(): int
{
return $this->argc;
}
@ -145,7 +145,7 @@ class Arguments
*
* @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);
}
@ -158,7 +158,7 @@ class 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
$server['QUERY_STRING'] = ltrim($server['QUERY_STRING'] ?? '', '/');

View file

@ -107,7 +107,7 @@ class BaseURL
*
* @return string
*/
public function getHostname()
public function getHostname(): string
{
return $this->hostname;
}
@ -117,7 +117,7 @@ class BaseURL
*
* @return string
*/
public function getScheme()
public function getScheme(): string
{
return $this->scheme;
}
@ -127,7 +127,7 @@ class BaseURL
*
* @return int
*/
public function getSSLPolicy()
public function getSSLPolicy(): int
{
return $this->sslPolicy;
}
@ -137,7 +137,7 @@ class BaseURL
*
* @return string
*/
public function getUrlPath()
public function getUrlPath(): string
{
return $this->urlPath;
}
@ -151,7 +151,7 @@ class BaseURL
*
* @return string
*/
public function get($ssl = false)
public function get(bool $ssl = false): string
{
if ($this->sslPolicy === self::SSL_POLICY_SELFSIGN && $ssl) {
return Network::switchScheme($this->url);
@ -168,8 +168,9 @@ class BaseURL
* @param string? $urlPath
*
* @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;
$currSSLPolicy = $this->sslPolicy;
@ -224,11 +225,11 @@ class BaseURL
/**
* Save the current url as base URL
*
* @param $url
* @param string $url
*
* @return bool true, if the save was successful
*/
public function saveByURL($url)
public function saveByURL(string $url): bool
{
$parsed = @parse_url($url);
@ -421,7 +422,7 @@ class BaseURL
*
* @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
$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
*/
public function redirect($toUrl = '', $ssl = false)
public function redirect(string $toUrl = '', bool $ssl = false)
{
if (!empty(parse_url($toUrl, PHP_URL_SCHEME))) {
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
*/
public function __toString()
public function __toString(): string
{
return $this->get();
return (string) $this->get();
}
}

View file

@ -130,7 +130,7 @@ class Mode
*
* @throws \Exception
*/
public function determine(BasePath $basepath, Database $database, Cache $configCache)
public function determine(BasePath $basepath, Database $database, Cache $configCache): Mode
{
$mode = 0;
@ -178,7 +178,7 @@ class 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) {
if (strpos(strtolower($server['HTTP_ACCEPT'] ?? ''), $type) !== false) {
@ -201,7 +201,7 @@ class Mode
*
* @return bool returns true, if the mode is set
*/
public function has($mode)
public function has(int $mode): bool
{
return ($this->mode & $mode) > 0;
}
@ -227,7 +227,7 @@ class Mode
*
* @return int Execution Mode
*/
public function getExecutor()
public function getExecutor(): int
{
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.
*
* @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) ||
!$this->has(MODE::DBCONFIGAVAILABLE);
@ -248,7 +248,7 @@ class Mode
*
* @return bool
*/
public function isNormal()
public function isNormal(): bool
{
return $this->has(Mode::LOCALCONFIGPRESENT) &&
$this->has(Mode::DBAVAILABLE) &&
@ -261,7 +261,7 @@ class Mode
*
* @return bool Is it a backend call
*/
public function isBackend()
public function isBackend(): bool
{
return $this->isBackend;
}
@ -271,7 +271,7 @@ class Mode
*
* @return bool true if it was an AJAX request
*/
public function isAjax()
public function isAjax(): bool
{
return $this->isAjax;
}
@ -281,7 +281,7 @@ class Mode
*
* @return bool true if it was an mobile request
*/
public function isMobile()
public function isMobile(): bool
{
return $this->isMobile;
}
@ -291,7 +291,7 @@ class Mode
*
* @return bool true if it was an tablet request
*/
public function isTablet()
public function isTablet(): bool
{
return $this->isTablet;
}

View file

@ -195,7 +195,7 @@ class Page implements ArrayAccess
* @param string $media
* @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]);
@ -288,7 +288,7 @@ class Page implements ArrayAccess
*
* Taken from http://webcheatsheet.com/php/get_current_page_url.php
*/
private function curPageURL()
private function curPageURL(): string
{
$pageURL = 'http';
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
*/
public function loadRoutes(array $routes)
public function loadRoutes(array $routes): Router
{
$routeCollector = ($this->routeCollector ?? new RouteCollector(new Std(), new GroupCountBased()));
@ -166,6 +166,13 @@ class Router
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)
{
foreach ($routes as $route => $config) {
@ -221,7 +228,7 @@ class Router
*
* @return bool
*/
private function isRoute(array $config)
private function isRoute(array $config): bool
{
return
// 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\NotFoundException If no rule matched
*/
private function getModuleClass()
private function getModuleClass(): string
{
$cmd = $this->args->getCommand();
$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;
}
@ -85,7 +87,7 @@ class BaseCollection extends \ArrayIterator
* @return array
* @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);
}
@ -97,7 +99,7 @@ class BaseCollection extends \ArrayIterator
* @return BaseCollection
* @see array_map()
*/
public function map(callable $callback)
public function map(callable $callback): BaseCollection
{
return new static(array_map($callback, $this->getArrayCopy()), $this->getTotalCount());
}
@ -110,7 +112,7 @@ class BaseCollection extends \ArrayIterator
* @return BaseCollection
* @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));
}

View file

@ -55,14 +55,14 @@ abstract class BaseEntity extends BaseDataTransferObject
}
/**
* @param $name
* @param mixed $name
* @return bool
* @throws HTTPException\InternalServerErrorException
*/
public function __isset($name)
public function __isset($name): bool
{
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);

View file

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

View file

@ -102,6 +102,7 @@ abstract class BaseModule implements ICanHandleRequests
* e.g. from protocol implementations.
*
* @param string[] $request The $_REQUEST content
* @return void
*/
protected function rawContent(array $request = [])
{
@ -117,6 +118,7 @@ abstract class BaseModule implements ICanHandleRequests
* XML feed or a JSON output.
*
* @param string[] $request The $_REQUEST content
* @return string
*/
protected function content(array $request = []): string
{
@ -130,6 +132,7 @@ abstract class BaseModule implements ICanHandleRequests
* Doesn't display any content
*
* @param string[] $request The $_REQUEST content
* @return void
*/
protected function delete(array $request = [])
{
@ -142,6 +145,7 @@ abstract class BaseModule implements ICanHandleRequests
* Doesn't display any content
*
* @param string[] $request The $_REQUEST content
* @return void
*/
protected function patch(array $request = [])
{
@ -154,7 +158,7 @@ abstract class BaseModule implements ICanHandleRequests
* Doesn't display any content
*
* @param string[] $request The $_REQUEST content
*
* @return void
*/
protected function post(array $request = [])
{
@ -168,6 +172,7 @@ abstract class BaseModule implements ICanHandleRequests
* Doesn't display any content
*
* @param string[] $request The $_REQUEST content
* @return void
*/
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
*
* @param array $input
* @param string $parameter
* @param mixed $default
* @param mixed $minimal_value
* @param mixed $maximum_value
* @return mixed
* @param array $input Input fields
* @param string $parameter Parameter
* @param mixed $default Default
* @param mixed $minimal_value Minimal value
* @param mixed $maximum_value Maximum value
* @return mixed null on error anything else on success (?)
*/
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;
}
/*
/**
* 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.
* 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.
* 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).
*
* @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']);
$timestamp = time();
@ -340,7 +348,14 @@ abstract class BaseModule implements ICanHandleRequests
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;
@ -372,12 +387,12 @@ abstract class BaseModule implements ICanHandleRequests
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;
}
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)) {
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)) {
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 = [
[

View file

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

View file

@ -32,7 +32,6 @@ use Friendica\Util\HTTPSignature;
use Friendica\Util\Images;
use Friendica\Util\Network;
use Friendica\Util\Proxy;
use Friendica\Util\Strings;
/**
* functions for handling contact avatar caching
@ -124,7 +123,7 @@ class Avatar
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));
@ -139,21 +138,19 @@ class Avatar
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');
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
$dir_perm = fileperms($dirpath) & 0777;
$file_perm = fileperms($dirpath) & 0666;
@ -198,7 +195,7 @@ class Avatar
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
{
$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 '';
}
$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) {
return '';
}
$filename = DI::basePath() . $parts['path'];
$filename = self::basePath() . substr($parts['path'], strlen($avatarpath));
DI::profiler()->startRecording('file');
$exists = file_exists($filename);
@ -269,4 +267,47 @@ class 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['protocol'] ?? Protocol::PHANTOM,
$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 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);
@ -102,7 +102,7 @@ class BoundariesPager extends Pager
* @return string HTML string of the pager
* @throws \Exception
*/
public function renderMinimal(int $itemCount)
public function renderMinimal(int $itemCount): string
{
$displayedItemCount = max(0, intval($itemCount));
@ -130,7 +130,7 @@ class BoundariesPager extends Pager
return Renderer::replaceMacros($tpl, ['pager' => $data]);
}
public function renderFull($itemCount)
public function renderFull(int $itemCount): string
{
throw new \BadMethodCallException();
}

View file

@ -41,7 +41,7 @@ class ContactSelector
* @param boolean $disabled optional, default false
* @return string
*/
public static function pollInterval($current, $disabled = false)
public static function pollInterval(string $current, bool $disabled = false): string
{
$dis = (($disabled) ? ' disabled="disabled" ' : '');
$o = '';
@ -84,7 +84,7 @@ class ContactSelector
* @return string Server URL
* @throws \Exception
*/
private static function getServerURLForProfile($profile)
private static function getServerURLForProfile(string $profile): string
{
if (!empty(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 $profile optional, default empty
* @param string $protocol (Optional) Protocol that is used for the transmission
* @param int $gsid Server id
* @return string
* @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 = [
Protocol::DFRN => DI::l10n()->t('DFRN'),
@ -179,12 +182,15 @@ class ContactSelector
}
/**
* Determines network's icon name
*
* @param string $network network
* @param string $profile optional, default empty
* @return string
* @param int $gsid Server id
* @return string Name for network icon
* @throws \Exception
*/
public static function networkToIcon($network, $profile = "", $gsid = 0)
public static function networkToIcon(string $network, string $profile = "", int $gsid = null): string
{
$nets = [
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
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;
}
@ -189,7 +189,7 @@ class Conversation
* @return string formatted text
* @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');
$o = '';
@ -275,7 +275,7 @@ class Conversation
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']);
if (empty($user['uid'])) {
@ -414,8 +414,8 @@ class Conversation
* figures out how to determine page owner and other contextual items
* that are based on unique features of the calling module.
* @param array $items
* @param $mode
* @param $update
* @param string $mode
* @param $update @TODO Which type?
* @param bool $preview
* @param string $order
* @param int $uid
@ -423,7 +423,7 @@ class Conversation
* @throws ImagickException
* @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');
@ -784,7 +784,7 @@ class Conversation
return $o;
}
private function getBlocklist()
private function getBlocklist(): array
{
if (!local_user()) {
return [];
@ -816,7 +816,7 @@ class Conversation
*
* @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');
@ -911,7 +911,7 @@ class Conversation
* @return array items with parents and comments
* @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');
if (count($parents) > 1) {
@ -1005,7 +1005,7 @@ class Conversation
* @param bool $recursive
* @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');
$children = [];
@ -1040,7 +1040,7 @@ class Conversation
* @param array $items
* @return array
*/
private function sortItemChildren(array $items)
private function sortItemChildren(array $items): array
{
$this->profiler->startRecording('rendering');
$result = $items;
@ -1086,7 +1086,7 @@ class Conversation
* @param array $parent A tree-like array of items
* @return array
*/
private function smartFlattenConversation(array $parent)
private function smartFlattenConversation(array $parent): array
{
$this->profiler->startRecording('rendering');
if (!isset($parent['children']) || count($parent['children']) == 0) {
@ -1142,7 +1142,7 @@ class Conversation
* @return array
* @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');
$parents = [];
@ -1222,7 +1222,7 @@ class Conversation
* @param array $b
* @return int
*/
private function sortThrFeaturedReceived(array $a, array $b)
private function sortThrFeaturedReceived(array $a, array $b): int
{
if ($b['featured'] && !$a['featured']) {
return 1;
@ -1240,7 +1240,7 @@ class Conversation
* @param array $b
* @return int
*/
private function sortThrFeaturedCommented(array $a, array $b)
private function sortThrFeaturedCommented(array $a, array $b): int
{
if ($b['featured'] && !$a['featured']) {
return 1;
@ -1258,7 +1258,7 @@ class Conversation
* @param array $b
* @return int
*/
private function sortThrReceived(array $a, array $b)
private function sortThrReceived(array $a, array $b): int
{
return strcmp($b['received'], $a['received']);
}
@ -1270,7 +1270,7 @@ class Conversation
* @param array $b
* @return int
*/
private function sortThrReceivedRev(array $a, array $b)
private function sortThrReceivedRev(array $a, array $b): int
{
return strcmp($a['received'], $b['received']);
}
@ -1282,7 +1282,7 @@ class Conversation
* @param array $b
* @return int
*/
private function sortThrCommented(array $a, array $b)
private function sortThrCommented(array $a, array $b): int
{
return strcmp($b['commented'], $a['commented']);
}
@ -1294,7 +1294,7 @@ class Conversation
* @param array $b
* @return int
*/
private function sortThrCreated(array $a, array $b)
private function sortThrCreated(array $a, array $b): int
{
return strcmp($b['created'], $a['created']);
}

View file

@ -160,7 +160,7 @@ class Pager
* @return string HTML string of the pager
* @throws \Exception
*/
public function renderMinimal(int $itemCount)
public function renderMinimal(int $itemCount): string
{
$displayedItemCount = max(0, intval($itemCount));
@ -199,13 +199,13 @@ class Pager
*
* $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
* @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 = [];

View file

@ -320,7 +320,7 @@ class BBCode
$post['text'] = trim(str_replace($pictures[0][0], '', $body));
} else {
$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['image'] = $pictures[0][1];
$post['preview'] = $pictures[0][2];
@ -1247,16 +1247,28 @@ class BBCode
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])) {
return ($match[1] . "[url]" . $match[2] . "[/url]");
return ($match[1] . '[url]' . $match[2] . '[/url]');
} 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
$own_photo_url = preg_quote(Strings::normaliseLink(DI::baseUrl()->get()) . '/photos/');
@ -1325,7 +1337,13 @@ class BBCode
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');
$return = preg_replace_callback("&\[url=([^\[\]]*)\]\[img=(.*)\](.*)\[\/img\]\[\/url\]&Usi", 'self::cleanPictureLinksCallback', $text);
@ -1334,7 +1352,13 @@ class BBCode
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');
$bbcode = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", ' $1 ', $bbcode);
@ -1350,10 +1374,10 @@ class BBCode
/**
* Replace names in mentions with nicknames
*
* @param string $body
* @param string $body HTML/BBCode
* @return string Body with replaced mentions
*/
public static function setMentionsToNicknames(string $body):string
public static function setMentionsToNicknames(string $body): string
{
DI::profiler()->startRecording('rendering');
$regexp = "/([@!])\[url\=([^\[\]]*)\].*?\[\/url\]/ism";
@ -1366,10 +1390,10 @@ class BBCode
* Callback function to replace a Friendica style mention in a mention with the nickname
*
* @param array $match Matching values for the callback
* @return string Replaced mention
* @return string Replaced mention or empty string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function mentionCallback($match)
private static function mentionCallback(array $match): string
{
if (empty($match[2])) {
return '';
@ -1407,7 +1431,7 @@ class BBCode
* @return string
* @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);
@ -1437,10 +1461,10 @@ class BBCode
* @param int $simple_html
* @param bool $for_plaintext
* @param int $uriid
* @return string
* @return string Converted code or empty string
* @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
if (is_null($text) || $text === '') {
@ -2142,7 +2166,7 @@ class BBCode
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
private static function bbCodeMention2DiasporaCallback($match)
private static function bbCodeMention2DiasporaCallback(array $match): string
{
$contact = Contact::getByURL($match[3], false, ['addr']);
if (empty($contact['addr'])) {
@ -2164,7 +2188,7 @@ class BBCode
* @return string
* @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');
$original_text = $text;
@ -2249,7 +2273,7 @@ class BBCode
*
* @return array List of tag and person names
*/
public static function getTags($string)
public static function getTags(string $string): array
{
DI::profiler()->startRecording('rendering');
$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
*
* @param string $body
* @param string $body HTML/BBCode
* @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,;:?!'\".])/",
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.
*
* @param string $text
* @param string $text HTML/BBCode
* @param array $tagList A list of tag names, e.g ['noparse', 'nobb', 'pre']
* @param callable $callback
* @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
*
* @param $body
* @param $profile_uid
* @param $network
* @return string
* @param string $body HTML/BBCode
* @param int $profile_uid Profile user id
* @param string $network Network name
* @return string HTML/BBCode with inserted images
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @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');
$body = self::performWithEscapedTags($body, ['noparse', 'pre', 'code', 'img'], function ($body) use ($profile_uid, $network) {
@ -2406,7 +2430,7 @@ class BBCode
* @return string
* @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');
$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.
* @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);
$replace = false;
@ -141,8 +141,16 @@ class HTML
* @return string
* @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');
$message = str_replace("\r", "", $message);
@ -409,7 +417,7 @@ class HTML
*
* @return string The expanded URL
*/
private static function qualifyURLsSub($matches, $basepath)
private static function qualifyURLsSub(array $matches, string $basepath): string
{
$base = parse_url($basepath);
unset($base['query']);
@ -436,7 +444,7 @@ class HTML
*
* @return string Body with expanded URLs
*/
private static function qualifyURLs($body, $basepath)
private static function qualifyURLs(string $body, string $basepath): string
{
$URLSearchString = "^\[\]";
@ -462,7 +470,7 @@ class HTML
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) {
$wraplength = 2000000;
@ -503,7 +511,7 @@ class HTML
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);
@ -539,7 +547,7 @@ class HTML
return implode("\n", $newlines);
}
private static function collectURLs($message)
private static function collectURLs(string $message): array
{
$pattern = '/<a.*?href="(.*?)".*?>(.*?)<\/a>/is';
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
* @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');
$message = str_replace("\r", "", $html);
@ -705,7 +713,7 @@ class HTML
* @param string $html
* @return string
*/
public static function toMarkdown($html)
public static function toMarkdown(string $html): string
{
DI::profiler()->startRecording('rendering');
$converter = new HtmlConverter(['hard_break' => true]);
@ -721,7 +729,7 @@ class HTML
* @param string $s
* @return string
*/
public static function toBBCodeVideo($s)
public static function toBBCodeVideo(string $s): string
{
$s = preg_replace(
'#<object[^>]+>(.*?)https?://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+)(.*?)</object>#ism',
@ -751,7 +759,7 @@ class HTML
* @param string $base base url
* @return string
*/
public static function relToAbs($text, $base)
public static function relToAbs(string $text, string $base): string
{
if (empty($base)) {
return $text;
@ -790,7 +798,7 @@ class HTML
* @return string html for loader
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public static function scrollLoader()
public static function scrollLoader(): string
{
$tpl = Renderer::getMarkupTemplate("scroll_loader.tpl");
return Renderer::replaceMacros($tpl, [
@ -819,7 +827,7 @@ class HTML
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @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
if (empty($contact['addr'])) {
@ -859,13 +867,12 @@ class HTML
*
* @param string $s Search query.
* @param string $id HTML id
* @param string $url Search url.
* @param bool $aside Display the search widgit aside.
*
* @return string Formatted HTML.
* @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';
@ -906,7 +913,7 @@ class HTML
* @param string $s
* @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("/\<(.*?)(src|href)=(.*?)\&amp\;(.*?)\>/ism", '<$1$2=$3&$4>', $s);
@ -923,7 +930,7 @@ class HTML
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public static function applyContentFilter($html, array $reasons)
public static function applyContentFilter(string $html, array $reasons): string
{
if (count($reasons)) {
$tpl = Renderer::getMarkupTemplate('wall/content_filter.tpl');
@ -943,7 +950,7 @@ class HTML
* @param string $s
* @return string
*/
public static function unamp($s)
public static function unamp(string $s): string
{
return str_replace('&amp;', '&', $s);
}

View file

@ -45,7 +45,7 @@ class Widget
* @return string
* @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(
'$connect' => DI::l10n()->t('Add New Contact'),
@ -58,8 +58,10 @@ class 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();
@ -97,7 +99,7 @@ class Widget
*
* @return array Unsupported networks
*/
public static function unavailableNetworks()
public static function unavailableNetworks(): array
{
// Always hide content from these networks
$networks = [Protocol::PHANTOM, Protocol::FACEBOOK, Protocol::APPNET, Protocol::ZOT];
@ -154,7 +156,7 @@ class Widget
* @return string
* @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);
$queryArray = [];
@ -191,7 +193,7 @@ class Widget
* @return string
* @throws \Exception
*/
public static function groups($baseurl, $selected = '')
public static function groups(string $baseurl, string $selected = ''): string
{
if (!local_user()) {
return '';

View file

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

View file

@ -49,6 +49,8 @@ class Hook
/**
* Load hooks
*
* @return void
*/
public static function loadHooks()
{
@ -69,8 +71,9 @@ class Hook
* @param string $hook
* @param string $file
* @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)) {
self::$hooks[$hook] = [];
@ -90,7 +93,7 @@ class Hook
* @return mixed|bool
* @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);
@ -111,7 +114,7 @@ class Hook
* @return boolean
* @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);
@ -120,8 +123,8 @@ class Hook
self::delete($condition);
$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
* @return array
*/
public static function getByName($name)
public static function getByName(string $name): array
{
$return = [];
@ -149,9 +152,10 @@ class Hook
* @param integer $priority of the hook
* @param string $name of the hook to call
* @param mixed $data to transmit to the callback handler
* @return void
* @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)) {
foreach (self::$hooks[$name] as $hook) {
@ -184,9 +188,10 @@ class Hook
*
* @param string $name of the hook to call
* @param string|array &$data to transmit to the callback handler
* @return void
* @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)) {
foreach (self::$hooks[$name] as $hook) {
@ -202,9 +207,10 @@ class Hook
* @param string $name of the hook to call
* @param array $hook Hook data
* @param string|array &$data to transmit to the callback handler
* @return void
* @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
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
* @return boolean
*/
public static function isAddonApp($name)
public static function isAddonApp(string $name): bool
{
$name = Strings::sanitizeFilePathItem($name);
@ -253,7 +259,7 @@ class Hook
* @return bool
* @throws \Exception
*/
public static function delete(array $condition)
public static function delete(array $condition): bool
{
$result = DBA::delete('hook', $condition);
@ -273,7 +279,7 @@ class Hook
* @return bool
* @throws \Exception
*/
private static function insert(array $condition)
private static function insert(array $condition): bool
{
$result = DBA::insert('hook', $condition);

View file

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

View file

@ -128,7 +128,7 @@ class L10n
private function setLangFromSession(IHandleSessions $session)
{
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
*
* @param string $lang language code to load
*
* @return void
* @throws \Exception
*/
private function loadTranslationTable($lang)
private function loadTranslationTable(string $lang)
{
$lang = Strings::sanitizeFilePathItem($lang);
@ -183,7 +183,7 @@ class L10n
*
* @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;
@ -269,7 +269,7 @@ class L10n
*
* @return string
*/
public function t($s, ...$vars)
public function t(string $s, ...$vars): string
{
if (empty($s)) {
return '';
@ -307,7 +307,7 @@ class L10n
* @return string
* @throws \Exception
*/
public function tt(string $singular, string $plural, int $count)
public function tt(string $singular, string $plural, int $count): string
{
$s = null;
@ -352,7 +352,7 @@ class L10n
*
* @return bool
*/
private function stringPluralSelectDefault($n)
private function stringPluralSelectDefault(int $n): bool
{
return $n != 1;
}
@ -369,7 +369,7 @@ class L10n
*
* @return array
*/
public static function getAvailableLanguages()
public static function getAvailableLanguages(): array
{
$langs = [];
$strings_file_paths = glob('view/lang/*/strings.php');
@ -391,10 +391,9 @@ class L10n
* Translate days and months names.
*
* @param string $s String with day or month name.
*
* @return string Translated string.
*/
public function getDay($s)
public function getDay(string $s): string
{
$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')],
@ -411,10 +410,9 @@ class L10n
* Translate short days and months names.
*
* @param string $s String with short day or month name.
*
* @return string Translated string.
*/
public function getDayShort($s)
public function getDayShort(string $s): string
{
$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')],
@ -435,7 +433,7 @@ class L10n
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @hook poke_verbs pokes array
*/
public function getPokeVerbs()
public function getPokeVerbs(): array
{
// index is present tense verb
// 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
* @throws \Exception
*/
public function withLang(string $lang)
public function withLang(string $lang): L10n
{
// Don't create a new instance for same language
if ($lang === $this->lang) {

View file

@ -47,7 +47,7 @@ class Logger
/**
* @return LoggerInterface
*/
private static function getWorker()
private static function getInstance()
{
if (self::$type === self::TYPE_LOGGER) {
return DI::logger();
@ -66,7 +66,7 @@ class Logger
public static function enableWorker(string $functionName)
{
self::$type = self::TYPE_WORKER;
self::getWorker()->setFunctionName($functionName);
self::getInstance()->setFunctionName($functionName);
}
/**
@ -82,15 +82,14 @@ class Logger
*
* @see LoggerInterface::emergency()
*
* @param string $message
* @param array $context
*
* @param string $message Message to log
* @param array $context Optional variables
* @return void
* @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
* trigger the SMS alerts and wake you up.
*
* @param string $message
* @param array $context
*
* @param string $message Message to log
* @param array $context Optional variables
* @return void
* @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.
*
* @param string $message
* @param array $context
*
* @param string $message Message to log
* @param array $context Optional variables
* @return void
* @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.
* @see LoggerInterface::error()
*
* @param string $message
* @param array $context
*
* @param string $message Message to log
* @param array $context Optional variables
* @return void
* @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
* that are not necessarily wrong.
*
* @param string $message
* @param array $context
*
* @param string $message Message to log
* @param array $context Optional variables
* @return void
* @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.
* @see LoggerInterface::notice()
*
* @param string $message
* @param array $context
*
* @param string $message Message to log
* @param array $context Optional variables
* @return void
* @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
* @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.
* @see LoggerInterface::debug()
*
* @param string $message
* @param array $context
*
* @param string $message Message to log
* @param array $context Optional variables
* @return void
* @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
* personally without background noise
*
* @param string $msg
* @param string $level
* @param string $message Message to log
* @param string $level Logging level
* @return void
* @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;
use Friendica\App\Request;
use Monolog\Handler;
use Monolog\Logger;
@ -38,15 +39,22 @@ class DevelopHandler extends Handler\AbstractHandler
private $developerIp;
/**
* @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
* @var string The IP of the current request
*/
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);
$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
if (!is_null($this->developerIp) && $_SERVER['REMOTE_ADDR'] != $this->developerIp) {
if (!is_null($this->developerIp) && $this->remoteAddress != $this->developerIp) {
return false;
}

View file

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

View file

@ -32,7 +32,7 @@ require_once 'boot.php';
*/
class Theme
{
public static function getAllowedList()
public static function getAllowedList(): array
{
$allowed_themes_str = DI::config()->get('system', 'allowed_themes');
$allowed_themes_raw = explode(',', str_replace(' ', '', $allowed_themes_str));
@ -69,7 +69,7 @@ class Theme
* @param string $theme the name of the theme
* @return array
*/
public static function getInfo($theme)
public static function getInfo(string $theme): array
{
$theme = Strings::sanitizeFilePathItem($theme);
@ -133,7 +133,7 @@ class Theme
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public static function getScreenshot($theme)
public static function getScreenshot(string $theme): string
{
$theme = Strings::sanitizeFilePathItem($theme);
@ -146,7 +146,13 @@ class Theme
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);
@ -167,10 +173,18 @@ class Theme
if ($key !== false) {
unset($allowed_themes[$key]);
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);
@ -208,7 +222,7 @@ class Theme
* @return string Path to the file or empty string if the file isn't found
* @throws \Exception
*/
public static function getPathForFile($file)
public static function getPathForFile(string $file): string
{
$a = DI::app();
@ -237,10 +251,9 @@ class Theme
* Provide a sane default if nothing is chosen or the specified theme does not exist.
*
* @param string $theme Theme name
*
* @return string
*/
public static function getStylesheetPath($theme)
public static function getStylesheetPath(string $theme): string
{
$theme = Strings::sanitizeFilePathItem($theme);
@ -263,10 +276,10 @@ class Theme
/**
* Returns the path of the provided theme
*
* @param $theme
* @param string $theme Theme name
* @return string|null
*/
public static function getConfigFile($theme)
public static function getConfigFile(string $theme)
{
$theme = Strings::sanitizeFilePathItem($theme);
@ -285,11 +298,11 @@ class Theme
/**
* 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
* @return string|null
*/
public static function getBackgroundColor(string $theme, $uid = null)
public static function getBackgroundColor(string $theme, int $uid = null)
{
$theme = Strings::sanitizeFilePathItem($theme);

View file

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

View file

@ -60,7 +60,7 @@ class Worker
* @return void
* @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);
@ -169,7 +169,7 @@ class Worker
*
* @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
if (self::tooMuchWorkers()) {
@ -204,7 +204,7 @@ class Worker
* @return boolean Returns "true" if tasks are existing
* @throws \Exception
*/
public static function entriesExists()
public static function entriesExists(): bool
{
$stamp = (float)microtime(true);
$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
* @throws \Exception
*/
private static function deferredEntries()
private static function deferredEntries(): int
{
$stamp = (float)microtime(true);
$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
* @throws \Exception
*/
private static function totalEntries()
private static function totalEntries(): int
{
$stamp = (float)microtime(true);
$count = DBA::count('workerqueue', ['done' => false, 'pid' => 0]);
@ -248,7 +248,7 @@ class Worker
* @return integer Number of active worker processes
* @throws \Exception
*/
private static function highestPriority()
private static function highestPriority(): int
{
$stamp = (float)microtime(true);
$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?
* @throws \Exception
*/
private static function processWithPriorityActive($priority)
private static function processWithPriorityActive(int $priority): int
{
$condition = ["`priority` <= ? AND `pid` != 0 AND NOT `done`", $priority];
return DBA::exists('workerqueue', $condition);
@ -281,7 +281,7 @@ class Worker
* @param mixed $file
* @return bool
*/
private static function validateInclude(&$file)
private static function validateInclude(&$file): bool
{
$orig_file = $file;
@ -321,7 +321,7 @@ class Worker
* @return boolean "true" if further processing should be stopped
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public static function execute($queue)
public static function execute(array $queue): bool
{
$mypid = getmypid();
@ -454,7 +454,7 @@ class Worker
* @return void
* @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();
@ -543,7 +543,7 @@ class Worker
* @return bool Are more than 3/4 of the maximum connections used?
* @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.
$max = DI::config()->get("system", "max_connections");
@ -627,7 +627,7 @@ class Worker
* @return bool Are there too much workers running?
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function tooMuchWorkers()
private static function tooMuchWorkers(): bool
{
$queues = DI::config()->get("system", "worker_queues", 10);
@ -751,7 +751,7 @@ class Worker
* @return integer Number of active worker processes
* @throws \Exception
*/
private static function activeWorkers()
private static function activeWorkers(): int
{
$stamp = (float)microtime(true);
$count = DI::process()->countCommand('Worker.php');
@ -766,7 +766,7 @@ class Worker
* @return array List of worker process ids
* @throws \Exception
*/
private static function getWorkerPIDList()
private static function getWorkerPIDList(): array
{
$ids = [];
$stamp = (float)microtime(true);
@ -787,7 +787,7 @@ class Worker
/**
* 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
*/
private static function getWaitingJobForPID()
@ -809,7 +809,7 @@ class Worker
* @return array array with next jobs
* @throws \Exception
*/
private static function nextProcess(int $limit)
private static function nextProcess(int $limit): array
{
$priority = self::nextPriority();
if (empty($priority)) {
@ -844,7 +844,7 @@ class Worker
/**
* Returns the priority of the next workerqueue job
*
* @return string priority
* @return string|bool priority or FALSE on failure
* @throws \Exception
*/
private static function nextPriority()
@ -915,7 +915,7 @@ class Worker
/**
* Find and claim the next worker process for us
*
* @return boolean Have we found something?
* @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function findWorkerProcesses()
@ -993,7 +993,7 @@ class Worker
* @return array worker processes
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public static function workerProcess()
public static function workerProcess(): array
{
// There can already be jobs for us in the queue.
$waiting = self::getWaitingJobForPID();
@ -1003,7 +1003,7 @@ class Worker
$stamp = (float)microtime(true);
if (!DI::lock()->acquire(self::LOCK_PROCESS)) {
return false;
return [];
}
self::$lock_duration += (microtime(true) - $stamp);
@ -1011,7 +1011,9 @@ class Worker
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
* @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')) {
self::forkProcess($do_cron);
@ -1231,7 +1233,7 @@ class Worker
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]);
}
@ -1244,7 +1246,7 @@ class Worker
* @param integer $max_level maximum retrial level
* @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']);
$retrial_time = time() - $created;
@ -1314,9 +1316,10 @@ class Worker
/**
* Check if the system is inside the defined maintenance window
*
* @param bool $check_last_execution Whether check last execution
* @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
$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';
public static function connect()
public static function connect(): bool
{
return DI::dba()->connect();
}
@ -58,7 +58,7 @@ class DBA
/**
* Perform a reconnect of an existing database connection
*/
public static function reconnect()
public static function reconnect(): bool
{
return DI::dba()->reconnect();
}
@ -77,7 +77,7 @@ class DBA
*
* @return string with either "pdo" or "mysqli"
*/
public static function getDriver()
public static function getDriver(): string
{
return DI::dba()->getDriver();
}
@ -90,7 +90,7 @@ class DBA
*
* @return string
*/
public static function serverInfo()
public static function serverInfo(): string
{
return DI::dba()->serverInfo();
}
@ -101,7 +101,7 @@ class DBA
* @return string
* @throws \Exception
*/
public static function databaseName()
public static function databaseName(): string
{
return DI::dba()->databaseName();
}
@ -112,7 +112,7 @@ class DBA
* @param string $str
* @return string escaped string
*/
public static function escape($str)
public static function escape(string $str): string
{
return DI::dba()->escape($str);
}
@ -122,7 +122,7 @@ class DBA
*
* @return boolean is the database connected?
*/
public static function connected()
public static function connected(): bool
{
return DI::dba()->connected();
}
@ -138,7 +138,7 @@ class DBA
* @param string $sql An SQL string without the values
* @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);
}
@ -152,7 +152,7 @@ class DBA
* @param string $sql An SQL string without the values
* @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", " "];
$replace = [' ', ' ', ' ', ' '];
@ -169,7 +169,7 @@ class DBA
* @param array $args Parameter array
* @return array universalized parameter array
*/
public static function getParam($args)
public static function getParam(array $args): array
{
unset($args[0]);
@ -192,7 +192,7 @@ class DBA
* @return bool|object statement object or result object
* @throws \Exception
*/
public static function p($sql)
public static function p(string $sql)
{
$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
* @throws \Exception
*/
public static function e($sql) {
public static function e(string $sql): bool
{
$params = self::getParam(func_get_args());
return DI::dba()->e($sql, $params);
@ -218,13 +218,12 @@ class DBA
/**
* Check if data exists
*
* @param string|array $table Table name or array [schema => table]
* @param array $condition array of fields for condition
*
* @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $condition Array of fields for condition
* @return boolean Are there rows for that condition?
* @throws \Exception
*/
public static function exists($table, $condition)
public static function exists(string $table, array $condition): bool
{
return DI::dba()->exists($table, $condition);
}
@ -238,7 +237,7 @@ class DBA
* @return array first row of query
* @throws \Exception
*/
public static function fetchFirst($sql)
public static function fetchFirst(string $sql)
{
$params = self::getParam(func_get_args());
@ -250,7 +249,7 @@ class DBA
*
* @return int Number of rows
*/
public static function affectedRows()
public static function affectedRows(): int
{
return DI::dba()->affectedRows();
}
@ -261,7 +260,7 @@ class DBA
* @param object Statement object
* @return int Number of columns
*/
public static function columnCount($stmt)
public static function columnCount($stmt): int
{
return DI::dba()->columnCount($stmt);
}
@ -271,7 +270,7 @@ class DBA
* @param PDOStatement|mysqli_result|mysqli_stmt Statement object
* @return int Number of rows
*/
public static function numRows($stmt)
public static function numRows($stmt): int
{
return DI::dba()->numRows($stmt);
}
@ -290,14 +289,13 @@ class DBA
/**
* Insert a row into a table
*
* @param string|array $table Table name or array [schema => table]
* @param array $param parameter array
* @param int $duplicate_mode What to do on a duplicated entry
*
* @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $param parameter array
* @param int $duplicate_mode What to do on a duplicated entry
* @return boolean was the insert successful?
* @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);
}
@ -306,13 +304,12 @@ class DBA
* 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.
*
* @param string|array $table Table name or array [schema => table]
* @param array $param parameter array
*
* @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $param parameter array
* @return boolean was the insert successful?
* @throws \Exception
*/
public static function replace($table, $param)
public static function replace(string $table, array $param): bool
{
return DI::dba()->replace($table, $param);
}
@ -322,7 +319,7 @@ class DBA
*
* @return integer Last inserted id
*/
public static function lastInsertId()
public static function lastInsertId(): int
{
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.
*
* @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?
* @throws \Exception
*/
public static function lock($table)
public static function lock(string $table): bool
{
return DI::dba()->lock($table);
}
@ -348,7 +344,7 @@ class DBA
* @return boolean was the unlock successful?
* @throws \Exception
*/
public static function unlock()
public static function unlock(): bool
{
return DI::dba()->unlock();
}
@ -358,7 +354,7 @@ class DBA
*
* @return boolean Was the command executed successfully?
*/
public static function transaction()
public static function transaction(): bool
{
return DI::dba()->transaction();
}
@ -368,7 +364,7 @@ class DBA
*
* @return boolean Was the command executed successfully?
*/
public static function commit()
public static function commit(): bool
{
return DI::dba()->commit();
}
@ -378,7 +374,7 @@ class DBA
*
* @return boolean Was the command executed successfully?
*/
public static function rollback()
public static function rollback(): bool
{
return DI::dba()->rollback();
}
@ -386,13 +382,13 @@ class DBA
/**
* Delete a row from a table
*
* @param string|array $table Table name
* @param array $conditions Field condition(s)
* @param string $table Table name
* @param array $conditions Field condition(s)
*
* @return boolean was the delete successful?
* @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);
}
@ -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.
* 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 $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)
@ -427,7 +423,7 @@ class DBA
* @return boolean was the update successfull?
* @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);
}
@ -435,7 +431,7 @@ class DBA
/**
* 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 $condition
* @param array $params
@ -443,7 +439,7 @@ class DBA
* @throws \Exception
* @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);
}
@ -451,16 +447,16 @@ class DBA
/**
* Select rows from a table and fills an array with the data
*
* @param string|array $table Table name or array [schema => table]
* @param array $fields Array of selected fields, empty for all
* @param array $condition Array of fields for condition
* @param array $params Array of several parameters
* @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 $condition Array of fields for condition
* @param array $params Array of several parameters
*
* @return array Data array
* @throws \Exception
* @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);
}
@ -468,10 +464,10 @@ class DBA
/**
* Select rows from a table
*
* @param string|array $table Table name or array [schema => table]
* @param array $fields Array of selected fields, empty for all
* @param array $condition Array of fields for condition
* @param array $params Array of several parameters
* @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 $condition Array of fields for condition
* @param array $params Array of several parameters
*
* @return boolean|object
*
@ -488,7 +484,7 @@ class DBA
* $data = DBA::select($table, $fields, $condition, $params);
* @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);
}
@ -496,9 +492,9 @@ class DBA
/**
* Counts the rows from a table satisfying the provided condition
*
* @param string|array $table Table name or array [schema => table]
* @param array $condition array of fields for condition
* @param array $params Array of several parameters
* @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $condition array of fields for condition
* @param array $params Array of several parameters
*
* @return int
*
@ -512,7 +508,7 @@ class DBA
* $count = DBA::count($table, $condition);
* @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);
}
@ -525,37 +521,30 @@ class DBA
* - [table1, table2, ...]
* - [schema1 => table1, schema2 => table2, table3, ...]
*
* @param string|array $tables
* @param array $tables Table names
* @return string
*/
public static function buildTableString($tables)
public static function buildTableString(array $tables): string
{
if (is_string($tables)) {
$tables = [$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);
// Quote each entry
return implode(',', array_map(['self', 'quoteIdentifier'], $tables));
}
/**
* Escape an identifier (table or field name)
* Escape an identifier (table or field name) optional with a schema like (schema.)table
*
* @param $identifier
* @return string
* @param $identifier Table, field name
* @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
* @return string
*/
public static function buildCondition(array &$condition = [])
public static function buildCondition(array &$condition = []): string
{
$condition = self::collapseCondition($condition);
@ -600,7 +589,7 @@ class DBA
* @param array $condition
* @return array
*/
public static function collapseCondition(array $condition)
public static function collapseCondition(array $condition): array
{
// Ensures an always true condition is returned
if (count($condition) < 1) {
@ -675,7 +664,7 @@ class DBA
* @return array A collapsed condition
* @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) {
return current($conditions);
@ -724,7 +713,7 @@ class DBA
* @param array $params
* @return string
*/
public static function buildParameter(array $params = [])
public static function buildParameter(array $params = []): string
{
$groupby_string = '';
if (!empty($params['group_by'])) {
@ -771,7 +760,7 @@ class DBA
*
* @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);
}
@ -783,7 +772,7 @@ class DBA
* @param array $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);
}
@ -793,7 +782,7 @@ class DBA
*
* @return string Error number (0 if no error)
*/
public static function errorNo()
public static function errorNo(): int
{
return DI::dba()->errorNo();
}
@ -803,7 +792,7 @@ class DBA
*
* @return string Error message ('' if no error)
*/
public static function errorMessage()
public static function errorMessage(): string
{
return DI::dba()->errorMessage();
}
@ -814,7 +803,7 @@ class DBA
* @param object $stmt statement object
* @return boolean was the close successful?
*/
public static function close($stmt)
public static function close($stmt): bool
{
return DI::dba()->close($stmt);
}
@ -827,7 +816,7 @@ class DBA
* 'amount' => Number of concurrent database processes
* @throws \Exception
*/
public static function processlist()
public static function processlist(): array
{
return DI::dba()->processlist();
}
@ -847,10 +836,9 @@ class DBA
* Checks if $array is 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
*/
public static function isResult($array)
public static function isResult($array): bool
{
return DI::dba()->isResult($array);
}
@ -862,7 +850,7 @@ class DBA
* @param boolean $add_quotation add quotation marks for string values
* @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);
}

View file

@ -84,7 +84,7 @@ class DBStructure
'deliverq', 'dsprphotoq', 'ffinder', 'sign', 'spam', 'term', 'user-item', 'thread', 'item', 'challenge',
'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']);
if (empty($tables)) {
@ -119,13 +119,13 @@ class DBStructure
public static function convertToInnoDB()
{
$tables = DBA::selectToArray(
['information_schema' => 'tables'],
'information_schema.tables',
['table_name'],
['engine' => 'MyISAM', 'table_schema' => DBA::databaseName()]
);
$tables = array_merge($tables, DBA::selectToArray(
['information_schema' => 'tables'],
'information_schema.tables',
['table_name'],
['engine' => 'InnoDB', 'ROW_FORMAT' => ['COMPACT', 'REDUNDANT'], 'table_schema' => DBA::databaseName()]
));
@ -150,10 +150,9 @@ class DBStructure
* Print out database error messages
*
* @param string $message Message to be added to the 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",
DBA::errorNo(), DBA::errorMessage());
@ -164,7 +163,7 @@ class DBStructure
public static function writeStructure()
{
$tables = [];
foreach (self::definition(null) as $name => $definition) {
foreach (self::definition('') as $name => $definition) {
$indexes = [[
'name' => 'Name',
'fields' => 'Fields',
@ -225,8 +224,8 @@ class DBStructure
$field['default'] = $value['default'] ?? 'NULL';
$field['extra'] = $value['extra'] ?? '';
foreach ($field as $fieldname => $fieldvalue) {
$lengths[$fieldname] = max($lengths[$fieldname] ?? 0, strlen($fieldvalue));
foreach ($field as $fieldName => $fieldvalue) {
$lengths[$fieldName] = max($lengths[$fieldName] ?? 0, strlen($fieldvalue));
}
$fields[] = $field;
@ -263,7 +262,7 @@ class DBStructure
file_put_contents($filename, $content);
}
public static function printStructure($basePath)
public static function printStructure(string $basePath)
{
$database = self::definition($basePath, false);
@ -288,12 +287,12 @@ class DBStructure
* On first pass, defines DB_UPDATE_VERSION constant.
*
* @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 boolean $with_addons_structure Whether to tack on addons additional tables
* @return array
* @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 (empty($basePath)) {
@ -303,7 +302,7 @@ class DBStructure
$filename = $basePath . '/static/dbstructure.config.php';
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;
@ -327,23 +326,23 @@ class DBStructure
/**
* Get field data for the given table
*
* @param string $table
* @param string $table Tavle to load field definitions for
* @param array $data data fields
* @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);
if (empty($definition[$table])) {
return [];
}
$fieldnames = array_keys($definition[$table]['fields']);
$fieldNames = array_keys($definition[$table]['fields']);
$fields = [];
// Assign all field that are present in the table
foreach ($fieldnames as $field) {
foreach ($fieldNames as $field) {
if (isset($data[$field])) {
// 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)) {
@ -358,45 +357,54 @@ class DBStructure
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;
$engine = "";
$comment = "";
$engine = '';
$comment = '';
$sql_rows = [];
$primary_keys = [];
$foreign_keys = [];
foreach ($structure["fields"] as $fieldname => $field) {
$sql_rows[] = "`" . DBA::escape($fieldname) . "` " . self::FieldCommand($field);
foreach ($structure['fields'] as $fieldName => $field) {
$sql_rows[] = '`' . DBA::escape($fieldName) . '` ' . self::FieldCommand($field);
if (!empty($field['primary'])) {
$primary_keys[] = $fieldname;
$primary_keys[] = $fieldName;
}
if (!empty($field['foreign'])) {
$foreign_keys[$fieldname] = $field;
$foreign_keys[$fieldName] = $field;
}
}
if (!empty($structure["indexes"])) {
foreach ($structure["indexes"] as $indexname => $fieldnames) {
$sql_index = self::createIndex($indexname, $fieldnames, "");
if (!empty($structure['indexes'])) {
foreach ($structure['indexes'] as $indexName => $fieldNames) {
$sql_index = self::createIndex($indexName, $fieldNames, '');
if (!is_null($sql_index)) {
$sql_rows[] = $sql_index;
}
}
}
foreach ($foreign_keys as $fieldname => $parameters) {
$sql_rows[] = self::foreignCommand($name, $fieldname, $parameters);
foreach ($foreign_keys as $fieldName => $parameters) {
$sql_rows[] = self::foreignCommand($name, $fieldName, $parameters);
}
if (isset($structure["engine"])) {
$engine = " ENGINE=" . $structure["engine"];
if (isset($structure['engine'])) {
$engine = ' ENGINE=' . $structure['engine'];
}
if (isset($structure["comment"])) {
$comment = " COMMENT='" . DBA::escape($structure["comment"]) . "'";
if (isset($structure['comment'])) {
$comment = " COMMENT='" . DBA::escape($structure['comment']) . "'";
}
$sql = implode(",\n\t", $sql_rows);
@ -414,71 +422,77 @@ class DBStructure
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"])) {
$fieldstruct .= " COLLATE " . $parameters["Collation"];
if (isset($parameters['Collation'])) {
$fieldstruct .= ' COLLATE ' . $parameters['Collation'];
}
if (isset($parameters["not null"])) {
$fieldstruct .= " NOT NULL";
if (isset($parameters['not null'])) {
$fieldstruct .= ' NOT NULL';
}
if (isset($parameters["default"])) {
if (strpos(strtolower($parameters["type"]), "int") !== false) {
$fieldstruct .= " DEFAULT " . $parameters["default"];
if (isset($parameters['default'])) {
if (strpos(strtolower($parameters['type']), 'int') !== false) {
$fieldstruct .= ' DEFAULT ' . $parameters['default'];
} else {
$fieldstruct .= " DEFAULT '" . $parameters["default"] . "'";
$fieldstruct .= " DEFAULT '" . $parameters['default'] . "'";
}
}
if (isset($parameters["extra"])) {
$fieldstruct .= " " . $parameters["extra"];
if (isset($parameters['extra'])) {
$fieldstruct .= ' ' . $parameters['extra'];
}
if (isset($parameters["comment"])) {
$fieldstruct .= " COMMENT '" . DBA::escape($parameters["comment"]) . "'";
if (isset($parameters['comment'])) {
$fieldstruct .= " COMMENT '" . DBA::escape($parameters['comment']) . "'";
}
/*if (($parameters["primary"] != "") && $create)
$fieldstruct .= " PRIMARY KEY";*/
/*if (($parameters['primary'] != '') && $create)
$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));
if ($method != "" && $method != "ADD") {
if ($method != '' && $method != 'ADD') {
throw new Exception("Invalid parameter 'method' in self::createIndex(): '$method'");
}
if (in_array($fieldnames[0], ["UNIQUE", "FULLTEXT"])) {
$index_type = array_shift($fieldnames);
if (in_array($fieldNames[0], ['UNIQUE', 'FULLTEXT'])) {
$index_type = array_shift($fieldNames);
$method .= " " . $index_type;
}
$names = "";
foreach ($fieldnames as $fieldname) {
if ($names != "") {
$names .= ",";
foreach ($fieldNames as $fieldName) {
if ($names != '') {
$names .= ',';
}
if (preg_match('|(.+)\((\d+)\)|', $fieldname, $matches)) {
if (preg_match('|(.+)\((\d+)\)|', $fieldName, $matches)) {
$names .= "`" . DBA::escape($matches[1]) . "`(" . intval($matches[2]) . ")";
} else {
$names .= "`" . DBA::escape($fieldname) . "`";
$names .= "`" . DBA::escape($fieldName) . "`";
}
}
if ($indexname == "PRIMARY") {
if ($indexName == 'PRIMARY') {
return sprintf("%s PRIMARY KEY(%s)", $method, $names);
}
$sql = sprintf("%s INDEX `%s` (%s)", $method, DBA::escape($indexname), $names);
return ($sql);
return sprintf("%s INDEX `%s` (%s)", $method, DBA::escape($indexName), $names);
}
/**
@ -500,7 +514,7 @@ class DBStructure
* @return string Empty string if the update is successful, error messages otherwise
* @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) {
DI::config()->set('system', 'maintenance', 1);
@ -524,7 +538,7 @@ class DBStructure
* @return string Empty string if the update is successful, error messages otherwise
* @throws Exception
*/
public static function install(string $basePath)
public static function install(string $basePath): string
{
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
* @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');
@ -606,15 +620,15 @@ class DBStructure
* or the definition differ from current status
* and index name doesn't start with "local_"
*/
foreach ($database[$name]["indexes"] as $indexname => $fieldnames) {
$current_index_definition = implode(",", $fieldnames);
if (isset($structure["indexes"][$indexname])) {
$new_index_definition = implode(",", $structure["indexes"][$indexname]);
foreach ($database[$name]["indexes"] as $indexName => $fieldNames) {
$current_index_definition = implode(",", $fieldNames);
if (isset($structure["indexes"][$indexName])) {
$new_index_definition = implode(",", $structure["indexes"][$indexName]);
} else {
$new_index_definition = "__NOT_SET__";
}
if ($current_index_definition != $new_index_definition && substr($indexname, 0, 6) != 'local_') {
$sql2 = self::dropIndex($indexname);
if ($current_index_definition != $new_index_definition && substr($indexName, 0, 6) != 'local_') {
$sql2 = self::dropIndex($indexName);
if ($sql3 == "") {
$sql3 = "ALTER" . $ignore . " TABLE `" . $name . "` " . $sql2;
} else {
@ -623,9 +637,9 @@ class DBStructure
}
}
// Compare the field structure field by field
foreach ($structure["fields"] as $fieldname => $parameters) {
if (!isset($database[$name]["fields"][$fieldname])) {
$sql2 = self::addTableField($fieldname, $parameters);
foreach ($structure["fields"] as $fieldName => $parameters) {
if (!isset($database[$name]["fields"][$fieldName])) {
$sql2 = self::addTableField($fieldName, $parameters);
if ($sql3 == "") {
$sql3 = "ALTER" . $ignore . " TABLE `" . $name . "` " . $sql2;
} else {
@ -633,7 +647,7 @@ class DBStructure
}
} else {
// 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
unset($parameters['relation']);
@ -653,7 +667,7 @@ class DBStructure
$current_field_definition = DBA::cleanQuery(implode(",", $field_definition));
$new_field_definition = DBA::cleanQuery(implode(",", $parameters));
if ($current_field_definition != $new_field_definition) {
$sql2 = self::modifyTableField($fieldname, $parameters);
$sql2 = self::modifyTableField($fieldName, $parameters);
if ($sql3 == "") {
$sql3 = "ALTER" . $ignore . " TABLE `" . $name . "` " . $sql2;
} else {
@ -670,15 +684,15 @@ class DBStructure
* Don't create keys if table is new
*/
if (!$is_new_table) {
foreach ($structure["indexes"] as $indexname => $fieldnames) {
if (isset($database[$name]["indexes"][$indexname])) {
$current_index_definition = implode(",", $database[$name]["indexes"][$indexname]);
foreach ($structure["indexes"] as $indexName => $fieldNames) {
if (isset($database[$name]["indexes"][$indexName])) {
$current_index_definition = implode(",", $database[$name]["indexes"][$indexName]);
} else {
$current_index_definition = "__NOT_SET__";
}
$new_index_definition = implode(",", $fieldnames);
$new_index_definition = implode(",", $fieldNames);
if ($current_index_definition != $new_index_definition) {
$sql2 = self::createIndex($indexname, $fieldnames);
$sql2 = self::createIndex($indexName, $fieldNames);
if ($sql2 != "") {
if ($sql3 == "") {
@ -694,17 +708,17 @@ class DBStructure
// Foreign keys
// Compare the field structure field by field
foreach ($structure["fields"] as $fieldname => $parameters) {
foreach ($structure["fields"] as $fieldName => $parameters) {
if (empty($parameters['foreign'])) {
continue;
}
$constraint = self::getConstraintName($name, $fieldname, $parameters);
$constraint = self::getConstraintName($name, $fieldName, $parameters);
unset($existing_foreign_keys[$constraint]);
if (empty($database[$name]['foreign_keys'][$constraint])) {
$sql2 = self::addForeignKey($name, $fieldname, $parameters);
$sql2 = self::addForeignKey($name, $fieldName, $parameters);
if ($sql3 == "") {
$sql3 = "ALTER" . $ignore . " TABLE `" . $name . "` " . $sql2;
@ -767,9 +781,9 @@ class DBStructure
// Now have a look at the field collations
// Compare the field structure field by field
foreach ($structure["fields"] as $fieldname => $parameters) {
foreach ($structure["fields"] as $fieldName => $parameters) {
// 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
if (!isset($parameters['Collation']) && !empty($field_definition['Collation'])) {
@ -779,7 +793,7 @@ class DBStructure
}
if ($field_definition['Collation'] != $parameters['Collation']) {
$sql2 = self::modifyTableField($fieldname, $parameters);
$sql2 = self::modifyTableField($fieldName, $parameters);
if (($sql3 == "") || (substr($sql3, -2, 2) == "; ")) {
$sql3 .= "ALTER" . $ignore . " TABLE `" . $name . "` " . $sql2;
} else {
@ -826,23 +840,29 @@ class DBStructure
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
$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_KEY', 'COLLATION_NAME', 'COLUMN_COMMENT'],
["`TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?",
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'],
["`TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `REFERENCED_TABLE_SCHEMA` IS NOT NULL",
DBA::databaseName(), $table]);
$table_status = DBA::selectFirst(['INFORMATION_SCHEMA' => 'TABLES'],
$table_status = DBA::selectFirst('INFORMATION_SCHEMA.TABLES',
['ENGINE', 'TABLE_COLLATION', 'TABLE_COMMENT'],
["`TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?",
DBA::databaseName(), $table]);
@ -909,41 +929,42 @@ class DBStructure
}
}
return ["fields" => $fielddata, "indexes" => $indexdata,
"foreign_keys" => $foreigndata, "table_status" => $table_status];
return [
'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 ($sql);
return sprintf("DROP INDEX `%s`", DBA::escape($indexName));
}
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 ($sql);
return sprintf("ADD `%s` %s", DBA::escape($fieldName), self::FieldCommand($parameters));
}
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 ($sql);
return sprintf("MODIFY `%s` %s", DBA::escape($fieldName), self::FieldCommand($parameters, false));
}
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_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_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'])) {
$sql .= " ON UPDATE " . strtoupper($parameters['foreign']['on update']);
@ -960,12 +981,12 @@ class DBStructure
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);
}
@ -983,7 +1004,7 @@ class DBStructure
* @return boolean Was the renaming successful?
* @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)) {
return false;
@ -1019,7 +1040,7 @@ class DBStructure
return false;
}
$sql .= ";";
$sql .= ';';
$stmt = DBA::p($sql);
@ -1043,7 +1064,7 @@ class DBStructure
* @return boolean Does the table exist?
* @throws Exception
*/
public static function existsColumn($table, $columns = [])
public static function existsColumn(string $table, array $columns = []): bool
{
if (empty($table)) {
return false;
@ -1079,39 +1100,33 @@ class DBStructure
/**
* Check if a foreign key exists for the given table field
*
* @param string $table
* @param string $field
* @return boolean
* @param string $table Table name
* @param string $field Field name
* @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",
DBA::databaseName(), $table, $field]);
}
/**
* Check if a table exists
*
* @param string|array $table Table name
* Check if a table exists
*
* @param string $table Single table name (please loop yourself)
* @return boolean Does the table exist?
* @throws Exception
*/
public static function existsTable($table)
public static function existsTable(string $table): bool
{
if (empty($table)) {
return false;
}
if (is_array($table)) {
$condition = ['table_schema' => key($table), 'table_name' => current($table)];
} else {
$condition = ['table_schema' => DBA::databaseName(), 'table_name' => $table];
}
$condition = ['table_schema' => DBA::databaseName(), 'table_name' => $table];
$result = DBA::exists(['information_schema' => 'tables'], $condition);
return $result;
return DBA::exists('information_schema.tables', $condition);
}
/**
@ -1122,7 +1137,7 @@ class DBStructure
* @return array An array of the table columns
* @throws Exception
*/
public static function getColumns($table)
public static function getColumns(string $table): array
{
$stmtColumns = DBA::p("SHOW COLUMNS FROM `" . $table . "`");
return DBA::toArray($stmtColumns);
@ -1130,6 +1145,9 @@ class DBStructure
/**
* 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)
{
@ -1163,9 +1181,9 @@ class DBStructure
if (self::existsTable('user') && !DBA::exists('user', ['uid' => 0])) {
$user = [
"verified" => true,
"page-flags" => User::PAGE_FLAGS_SOAPBOX,
"account-type" => User::ACCOUNT_TYPE_RELAY,
'verified' => true,
'page-flags' => User::PAGE_FLAGS_SOAPBOX,
'account-type' => User::ACCOUNT_TYPE_RELAY,
];
DBA::insert('user', $user);
$lastid = DBA::lastInsertId();
@ -1265,12 +1283,14 @@ class DBStructure
*
* @return boolean
*/
private static function isUpdating()
private static function isUpdating(): bool
{
$isUpdate = false;
$processes = DBA::select(['information_schema' => 'processlist'], ['info'],
['db' => DBA::databaseName(), 'command' => ['Query', 'Execute']]);
$processes = DBA::select('information_schema.processlist', ['info'], [
'db' => DBA::databaseName(),
'command' => ['Query', 'Execute']
]);
while ($process = DBA::fetch($processes)) {
$parts = explode(' ', $process['info']);

View file

@ -26,6 +26,7 @@ use Friendica\Core\System;
use Friendica\Network\HTTPException\ServiceUnavailableException;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Profiler;
use InvalidArgumentException;
use mysqli;
use mysqli_result;
use mysqli_stmt;
@ -63,7 +64,7 @@ class Database
protected $server_info = '';
/** @var PDO|mysqli */
protected $connection;
protected $driver;
protected $driver = '';
protected $pdo_emulate_prepares = false;
private $error = false;
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()) {
return $this->connected;
@ -175,7 +181,7 @@ class Database
// No suitable SQL driver was found.
if (!$this->connected) {
$this->driver = null;
$this->driver = '';
$this->connection = null;
}
@ -227,7 +233,7 @@ class Database
}
}
$this->driver = null;
$this->driver = '';
$this->connected = false;
}
@ -255,7 +261,7 @@ class Database
*
* @return string with either "pdo" or "mysqli"
*/
public function getDriver()
public function getDriver(): string
{
return $this->driver;
}
@ -266,9 +272,9 @@ class Database
* This function discriminate between the deprecated mysql API and the current
* 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 == '') {
switch ($this->driver) {
@ -286,10 +292,10 @@ class Database
/**
* Returns the selected database name
*
* @return string
* @return string Database name
* @throws \Exception
*/
public function databaseName()
public function databaseName(): string
{
$ret = $this->p("SELECT DATABASE() AS `db`");
$data = $this->toArray($ret);
@ -300,10 +306,10 @@ class Database
* Analyze a database query and log this if some conditions are met.
*
* @param string $query The database query that will be analyzed
*
* @return void
* @throws \Exception
*/
private function logIndex($query)
private function logIndex(string $query)
{
if (!$this->configCache->get('system', 'db_log_index')) {
@ -359,11 +365,10 @@ class Database
* Removes every not allowlisted character from the identifier string
*
* @param string $identifier
*
* @return string sanitized identifier
* @throws \Exception
*/
private function sanitizeIdentifier($identifier)
private function sanitizeIdentifier(string $identifier): string
{
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;
}
/**
* Checks connection status
*
* @return bool Whether connection to database was success
*/
public function connected()
{
$connected = false;
@ -424,7 +439,7 @@ class Database
*
* @return string The input SQL string modified if necessary.
*/
public function anyValueFallback($sql)
public function anyValueFallback(string $sql): string
{
$server_info = $this->serverInfo();
if (version_compare($server_info, '5.7.5', '<') ||
@ -442,7 +457,7 @@ class Database
*
* @return string The replaced SQL query
*/
private function replaceParameters($sql, $args)
private function replaceParameters(string $sql, array $args): string
{
$offset = 0;
foreach ($args as $param => $value) {
@ -476,7 +491,7 @@ class Database
* @return bool|object statement object or result object
* @throws \Exception
*/
public function p($sql)
public function p(string $sql)
{
$this->profiler->startRecording('database');
@ -541,7 +556,7 @@ class Database
if (!$retval = $this->connection->query($this->replaceParameters($sql, $args))) {
$errorInfo = $this->connection->errorInfo();
$this->error = $errorInfo[2];
$this->errorno = $errorInfo[1];
$this->errorno = (int) $errorInfo[1];
$retval = false;
$is_error = true;
break;
@ -554,7 +569,7 @@ class Database
if (!$stmt = $this->connection->prepare($sql)) {
$errorInfo = $this->connection->errorInfo();
$this->error = $errorInfo[2];
$this->errorno = $errorInfo[1];
$this->errorno = (int) $errorInfo[1];
$retval = false;
$is_error = true;
break;
@ -574,7 +589,7 @@ class Database
if (!$stmt->execute()) {
$errorInfo = $stmt->errorInfo();
$this->error = $errorInfo[2];
$this->errorno = $errorInfo[1];
$this->errorno = (int) $errorInfo[1];
$retval = false;
$is_error = true;
} else {
@ -709,7 +724,7 @@ class Database
}
$this->error = $error;
$this->errorno = $errorno;
$this->errorno = (int) $errorno;
}
$this->profiler->stopRecording();
@ -741,8 +756,9 @@ class Database
* @return boolean Was the query successfull? False is returned only if an error occurred
* @throws \Exception
*/
public function e($sql)
public function e(string $sql): bool
{
$retval = false;
$this->profiler->startRecording('database_write');
@ -804,13 +820,13 @@ class Database
/**
* Check if data exists
*
* @param string|array $table Table name or array [schema => table]
* @param array $condition array of fields for condition
* @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $condition Array of fields for condition
*
* @return boolean Are there rows for that condition?
* @throws \Exception
*/
public function exists($table, $condition)
public function exists(string $table, array $condition): bool
{
if (empty($table)) {
return false;
@ -850,10 +866,10 @@ class Database
*
* @param string $sql SQL statement
*
* @return array first row of query
* @return array|bool first row of query or false on failure
* @throws \Exception
*/
public function fetchFirst($sql)
public function fetchFirst(string $sql)
{
$params = DBA::getParam(func_get_args());
@ -875,7 +891,7 @@ class Database
*
* @return int Number of rows
*/
public function affectedRows()
public function affectedRows(): int
{
return $this->affected_rows;
}
@ -887,7 +903,7 @@ class Database
*
* @return int Number of columns
*/
public function columnCount($stmt)
public function columnCount($stmt): int
{
if (!is_object($stmt)) {
return 0;
@ -908,7 +924,7 @@ class Database
*
* @return int Number of rows
*/
public function numRows($stmt)
public function numRows($stmt): int
{
if (!is_object($stmt)) {
return 0;
@ -927,7 +943,7 @@ class Database
*
* @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)
{
@ -987,14 +1003,14 @@ class Database
/**
* 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 array $param parameter array
* @param int $duplicate_mode What to do on a duplicated entry
* @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $param parameter array
* @param int $duplicate_mode What to do on a duplicated entry
*
* @return boolean was the insert successful?
* @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)) {
$this->logger->info('Table and fields have to be set');
@ -1003,7 +1019,7 @@ class Database
$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)));
@ -1038,13 +1054,12 @@ class Database
* 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.
*
* @param string|array $table Table name or array [schema => table]
* @param array $param parameter array
*
* @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $param parameter array
* @return boolean was the insert successful?
* @throws \Exception
*/
public function replace($table, array $param)
public function replace(string $table, array $param): bool
{
if (empty($table) || empty($param)) {
$this->logger->info('Table and fields have to be set');
@ -1053,7 +1068,7 @@ class Database
$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)));
@ -1069,7 +1084,7 @@ class Database
*
* @return integer Last inserted id
*/
public function lastInsertId()
public function lastInsertId(): int
{
switch ($this->driver) {
case self::PDO:
@ -1087,12 +1102,11 @@ class Database
*
* 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?
* @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
if ($this->driver == self::PDO) {
@ -1102,7 +1116,7 @@ class Database
$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) {
$this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, $this->pdo_emulate_prepares);
@ -1126,7 +1140,7 @@ class Database
* @return boolean was the unlock successful?
* @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
$this->performCommit();
@ -1177,7 +1191,12 @@ class Database
return true;
}
protected function performCommit()
/**
* Performs the commit
*
* @return boolean Was the command executed successfully?
*/
protected function performCommit(): bool
{
switch ($this->driver) {
case self::PDO:
@ -1199,7 +1218,7 @@ class Database
*
* @return boolean Was the command executed successfully?
*/
public function commit()
public function commit(): bool
{
if (!$this->performCommit()) {
return false;
@ -1213,7 +1232,7 @@ class Database
*
* @return boolean Was the command executed successfully?
*/
public function rollback()
public function rollback(): bool
{
$ret = false;
@ -1230,6 +1249,7 @@ class Database
$ret = $this->connection->rollback();
break;
}
$this->in_transaction = false;
return $ret;
}
@ -1243,14 +1263,14 @@ class Database
* @return boolean was the delete successful?
* @throws \Exception
*/
public function delete($table, array $conditions)
public function delete(string $table, array $conditions): bool
{
if (empty($table) || empty($conditions)) {
$this->logger->info('Table and conditions have to be set');
return false;
}
$table_string = DBA::buildTableString($table);
$table_string = DBA::buildTableString([$table]);
$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.
* 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 $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)
@ -1288,8 +1308,9 @@ class Database
*
* @return boolean was the update successfull?
* @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)) {
$this->logger->info('Table, fields and condition have to be set');
@ -1322,7 +1343,7 @@ class Database
$fields = $this->castFields($table, $fields);
$table_string = DBA::buildTableString($table);
$table_string = DBA::buildTableString([$table]);
$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
*
* @param string|array $table
* @param array $fields
* @param array $condition
* @param array $params
* @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 $condition Array of fields for condition
* @param array $params Array of several parameters
*
* @return bool|array
* @throws \Exception
* @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;
$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
*
* @param string|array $table Table name or array [schema => table]
* @param array $fields Array of selected fields, empty for all
* @param array $condition Array of fields for condition
* @param array $params Array of several parameters
*
* @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 $condition Array of fields for condition
* @param array $params Array of several parameters
* @return array Data array
* @throws \Exception
* @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));
}
@ -1390,9 +1410,9 @@ class Database
*
* @param array $fields
* @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.
// 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);
*
* @param string|array $table Table name or array [schema => table]
* @param array $fields Array of selected fields, empty for all
* @param array $condition Array of fields for condition
* @param array $params Array of several parameters
* @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 $condition Array of fields for condition
* @param array $params Array of several parameters
* @return boolean|object
* @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)) {
return false;
@ -1466,7 +1486,7 @@ class Database
$select_string = '*';
}
$table_string = DBA::buildTableString($table);
$table_string = DBA::buildTableString([$table]);
$condition_string = DBA::buildCondition($condition);
@ -1486,11 +1506,11 @@ class Database
/**
* Counts the rows from a table satisfying the provided condition
*
* @param string|array $table Table name or array [schema => table]
* @param array $condition Array of fields for condition
* @param array $params Array of several parameters
* @param string $table Table name in format schema.table (while scheme is optiona)
* @param array $condition Array of fields for condition
* @param array $params Array of several parameters
*
* @return int
* @return int Count of rows
*
* Example:
* $table = "post";
@ -1502,13 +1522,13 @@ class Database
* $count = DBA::count($table, $condition);
* @throws \Exception
*/
public function count($table, array $condition = [], array $params = [])
public function count(string $table, array $condition = [], array $params = []): int
{
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);
@ -1541,7 +1561,7 @@ class Database
*
* @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)) {
return [];
@ -1569,7 +1589,8 @@ class Database
* @param array $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
if (empty($fields)) {
return $fields;
@ -1595,7 +1616,7 @@ class Database
return $fields;
}
foreach(array_keys($fields) as $field) {
foreach (array_keys($fields) as $field) {
if (!empty($views[$table]['fields'][$field])) {
$viewdef = $views[$table]['fields'][$field];
if (!empty($tables[$viewdef[0]]['fields'][$viewdef[1]]['type'])) {
@ -1632,7 +1653,7 @@ class Database
*
* @return string Error number (0 if no error)
*/
public function errorNo()
public function errorNo(): int
{
return $this->errorno;
}
@ -1642,7 +1663,7 @@ class Database
*
* @return string Error message ('' if no error)
*/
public function errorMessage()
public function errorMessage(): string
{
return $this->error;
}
@ -1654,7 +1675,7 @@ class Database
*
* @return boolean was the close successful?
*/
public function close($stmt)
public function close($stmt): bool
{
$this->profiler->startRecording('database');
@ -1696,7 +1717,7 @@ class Database
* 'amount' => Number of concurrent database processes
* @throws \Exception
*/
public function processlist()
public function processlist(): array
{
$ret = $this->p("SHOW PROCESSLIST");
$data = $this->toArray($ret);
@ -1727,7 +1748,8 @@ class Database
* Fetch a database variable
*
* @param string $name
* @return string content
* @return string|null content or null if inexistent
* @throws \Exception
*/
public function getVariable(string $name)
{
@ -1739,10 +1761,9 @@ class Database
* Checks if $array is 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
*/
public function isResult($array)
public function isResult($array): bool
{
// It could be a return value from an update statement
if (is_bool($array)) {
@ -1762,10 +1783,9 @@ class Database
* @param mixed $value Array value
* @param string $key Array key
* @param boolean $add_quotation add quotation marks for string values
*
* @return void
*/
private function escapeArrayCallback(&$value, $key, $add_quotation)
private function escapeArrayCallback(&$value, string $key, bool $add_quotation)
{
if (!$add_quotation) {
if (is_bool($value)) {
@ -1790,10 +1810,9 @@ class Database
*
* @param mixed $arr Array with values to be escaped
* @param boolean $add_quotation add quotation marks for string values
*
* @return void
*/
public function escapeArray(&$arr, $add_quotation = false)
public function escapeArray(&$arr, bool $add_quotation = false)
{
array_walk($arr, [$this, 'escapeArrayCallback'], $add_quotation);
}
@ -1801,13 +1820,14 @@ class Database
/**
* 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 string $search
* @param string $replace
* @param string $search String to search for
* @param string $replace String to replace with
* @return void
* @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);
$replace = $this->escape($replace);
@ -1820,9 +1840,10 @@ class Database
$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)) {
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_iid = $max_item_delivery_data['iid'];
$max_iid = $max_item_delivery_data['iid'] ?? 0;
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.
*
* @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 boolean $with_addons_structure Whether to tack on addons additional tables
* @return array
* @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 (empty($basePath)) {
@ -75,6 +75,13 @@ class View
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)
{
// Delete previously used views that aren't used anymore
@ -94,11 +101,17 @@ class View
$definition = self::definition();
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);
@ -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;
$sql_rows = [];
foreach ($structure["fields"] as $fieldname => $origin) {
foreach ($structure['fields'] as $fieldname => $origin) {
if (is_string($origin)) {
$sql_rows[] = $origin . " AS `" . DBA::escape($fieldname) . "`";
} elseif (is_array($origin) && (sizeof($origin) == 2)) {
@ -159,9 +181,9 @@ class View
* @param string $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]);
if (empty($status['TABLE_TYPE'])) {
@ -177,9 +199,9 @@ class View
* @param string $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]);
if (empty($status['TABLE_TYPE'])) {

View file

@ -57,7 +57,7 @@ class Account extends BaseFactory
* @throws HTTPException\InternalServerErrorException
* @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']);
if (empty($contact)) {
@ -74,7 +74,7 @@ class Account extends BaseFactory
* @throws HTTPException\InternalServerErrorException
* @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]]);
if (empty($account)) {

View file

@ -190,7 +190,7 @@ class Status extends BaseFactory
*/
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)) {
$this->mstdnErrorFactory->RecordNotFound();
}

View file

@ -70,6 +70,7 @@ class Status extends BaseFactory
/**
* @param int $uriId Uri-ID of the item
* @param int $uid Item user
* @param bool $include_entities Whether to include entities
*
* @return \Friendica\Object\Api\Twitter\Status
* @throws HTTPException\InternalServerErrorException
@ -90,12 +91,13 @@ class Status extends BaseFactory
/**
* @param int $uriId Uri-ID of the item
* @param int $uid Item user
* @param bool $include_entities Whether to include entities
*
* @return \Friendica\Object\Api\Twitter\Status
* @throws HTTPException\InternalServerErrorException
* @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',
'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 int $uid Item user
* @param bool $include_entities Whether to include entities
*
* @return \Friendica\Object\Api\Twitter\Status
* @throws HTTPException\InternalServerErrorException

View file

@ -51,7 +51,7 @@ class User extends BaseFactory
* @throws HTTPException\InternalServerErrorException
* @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);
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);
}
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);
}

View file

@ -57,7 +57,7 @@ class LegacyModule extends BaseModule
* @param string $file_path
* @throws \Exception
*/
private function setModuleFile($file_path)
private function setModuleFile(string $file_path)
{
if (!is_readable($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
* @throws \Exception
*/
private function runModuleFunction(string $function_suffix)
private function runModuleFunction(string $function_suffix): string
{
$function_name = $this->moduleName . '_' . $function_suffix;

View file

@ -48,7 +48,7 @@ class APContact
* @param string $addr Address
* @return array webfinger data
*/
private static function fetchWebfingerData(string $addr)
private static function fetchWebfingerData(string $addr): array
{
$addr_parts = explode('@', $addr);
if (count($addr_parts) != 2) {
@ -116,15 +116,16 @@ class APContact
* @return array profile array
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @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)) {
Logger::info('Domain is blocked', ['url' => $url]);
return [];
}
$fetched_contact = false;
$fetched_contact = [];
if (empty($update)) {
if (is_null($update)) {
@ -220,14 +221,14 @@ class APContact
$apcontact['type'] = str_replace('as:', '', JsonLD::fetchElement($compacted, '@type'));
$apcontact['following'] = JsonLD::fetchElement($compacted, 'as:following', '@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);
$apcontact['outbox'] = JsonLD::fetchElement($compacted, 'as:outbox', '@id');
$apcontact['sharedinbox'] = '';
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);
}
@ -241,9 +242,10 @@ class APContact
$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');
if (!empty($ims)) {
foreach ($ims as $link) {
if (substr($link, 0, 5) == 'xmpp:') {
@ -525,8 +527,9 @@ class APContact
*
* @param string $url inbox url
* @param boolean $shared Shared Inbox
* @return void
*/
private static function unarchiveInbox($url, $shared)
private static function unarchiveInbox(string $url, bool $shared)
{
if (empty($url)) {
return;

View file

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

View file

@ -119,7 +119,7 @@ class Contact
* @return array
* @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);
}
@ -128,7 +128,7 @@ class Contact
* @param array $fields Array of selected fields, empty for all
* @param array $condition Array of fields for condition
* @param array $params Array of several parameters
* @return array
* @return array|bool
* @throws \Exception
*/
public static function selectFirst(array $fields = [], array $condition = [], array $params = [])
@ -148,7 +148,7 @@ class Contact
* @return int id of the created contact
* @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'])) {
$fields['gsid'] = GServer::getID($fields['baseurl'], true);
@ -187,6 +187,7 @@ class Contact
*
* @return boolean was the update successfull?
* @throws \Exception
* @todo Let's get rid of boolean type of $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
* @throws \Exception
*/
public static function getById($id, $fields = [])
public static function getById(int $id, array $fields = [])
{
return DBA::selectFirst('contact', $fields, ['id' => $id]);
}
@ -217,7 +218,7 @@ class Contact
* @return array|boolean Contact record if it exists, false otherwise
* @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']]);
}
@ -231,7 +232,7 @@ class Contact
* @param integer $uid User ID of the contact
* @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)) {
$cid = self::getIdForURL($url, $uid, $update);
@ -302,7 +303,7 @@ class Contact
* @param array $fields Field list
* @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) {
$contact = self::getByURL($url, $update, $fields, $uid);
@ -333,7 +334,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
public static function isFollower($cid, $uid)
public static function isFollower(int $cid, int $uid): bool
{
if (Contact\User::isBlocked($cid, $uid)) {
return false;
@ -358,7 +359,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
public static function isFollowerByURL($url, $uid)
public static function isFollowerByURL(string $url, uid $uid): bool
{
$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 $uid User ID
*
* @return boolean is the contact url being followed?
* @return boolean is the contact sharing with given user?
* @throws HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
public static function isSharing($cid, $uid)
public static function isSharing(int $cid, int $uid): bool
{
if (Contact\User::isBlocked($cid, $uid)) {
return false;
@ -404,7 +405,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
public static function isSharingByURL($url, $uid)
public static function isSharingByURL(string $url, int $uid): bool
{
$cid = self::getIdForURL($url, $uid);
@ -425,7 +426,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException
* @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)]);
if (!DBA::isResult($contact)) {
@ -459,7 +460,7 @@ class Contact
*
* @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)) {
$addr_parts = explode('@', $url);
@ -476,7 +477,7 @@ class Contact
*
* @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]);
if (!DBA::isResult($contact)) {
@ -500,7 +501,7 @@ class Contact
* @return integer|boolean Public contact id for given user id
* @throws \Exception
*/
public static function getPublicIdByUserId($uid)
public static function getPublicIdByUserId(int $uid)
{
$self = DBA::selectFirst('contact', ['url'], ['self' => true, 'uid' => $uid]);
if (!DBA::isResult($self)) {
@ -519,7 +520,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException
* @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
if (DI::config()->get('system', 'post_update_version') < 1427) {
@ -560,7 +561,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
private static function legacyGetPublicAndUserContactID($cid, $uid)
private static function legacyGetPublicAndUserContactID(int $cid, int $uid): array
{
if (empty($uid) || empty($cid)) {
return [];
@ -1526,7 +1527,7 @@ class Contact
* @param int $type type of contact or account
* @return string
*/
public static function getAccountType(int $type)
public static function getAccountType(int $type): string
{
switch ($type) {
case self::TYPE_ORGANISATION:
@ -1552,11 +1553,11 @@ class Contact
/**
* Blocks a contact
*
* @param int $cid
* @return bool
* @throws \Exception
* @param int $cid Contact id to block
* @param string $reason Block reason
* @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]);
@ -1566,11 +1567,10 @@ class Contact
/**
* Unblocks a contact
*
* @param int $cid
* @return bool
* @throws \Exception
* @param int $cid Contact id to unblock
* @return bool Whether it was successfull
*/
public static function unblock($cid)
public static function unblock(int $cid): bool
{
$return = self::update(['blocked' => false, 'block_reason' => null], ['id' => $cid]);
@ -1580,7 +1580,7 @@ class Contact
/**
* Ensure that cached avatar exist
*
* @param integer $cid
* @param integer $cid Contact id
*/
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
* @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);
@ -1654,7 +1654,7 @@ class Contact
* @param bool $no_update Don't perfom an update if no cached avatar was found
* @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);
}
@ -1666,7 +1666,7 @@ class Contact
* @param bool $no_update Don't perfom an update if no cached avatar was found
* @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);
}
@ -1678,7 +1678,7 @@ class Contact
* @param bool $no_update Don't perfom an update if no cached avatar was found
* @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);
}
@ -1690,7 +1690,7 @@ class Contact
* @param bool $no_update Don't perfom an update if no cached avatar was found
* @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;
$contact_fields = [];
@ -1796,7 +1796,7 @@ class Contact
* @param string $size Size of the avatar picture
* @return string avatar URL
*/
public static function getDefaultAvatar(array $contact, string $size)
public static function getDefaultAvatar(array $contact, string $size): string
{
switch ($size) {
case Proxy::SIZE_MICRO:
@ -1817,6 +1817,114 @@ class Contact
}
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;
}
@ -2506,7 +2614,7 @@ class Contact
* @throws HTTPException\NotFoundException
* @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' => ''];
@ -2695,7 +2803,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException
* @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
if (empty($datarray['author-id'])) {
@ -2922,7 +3030,7 @@ class Contact
* @return array
* @throws \Exception
*/
public static function pruneUnavailable(array $contact_ids)
public static function pruneUnavailable(array $contact_ids): array
{
if (empty($contact_ids)) {
return [];
@ -2950,7 +3058,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
public static function magicLink($contact_url, $url = '')
public static function magicLink(string $contact_url, string $url = ''): string
{
if (!Session::isAuthenticated()) {
return $url ?: $contact_url; // Equivalent to: ($url != '') ? $url : $contact_url;
@ -2977,7 +3085,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException
* @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]);
@ -2994,7 +3102,7 @@ class Contact
* @throws HTTPException\InternalServerErrorException
* @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'];
@ -3035,7 +3143,7 @@ class Contact
*
* @return boolean "true" if it is a forum
*/
public static function isForum($contactid)
public static function isForum(int $contactid): bool
{
$fields = ['contact-type'];
$condition = ['id' => $contactid];
@ -3054,7 +3162,7 @@ class Contact
* @param array $contact
* @return bool
*/
public static function canReceivePrivateMessages(array $contact)
public static function canReceivePrivateMessages(array $contact): bool
{
$protocol = $contact['network'] ?? $contact['protocol'] ?? Protocol::PHANTOM;
$self = $contact['self'] ?? false;
@ -3072,7 +3180,7 @@ class Contact
* @return array with search results
* @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)) {
return [];
@ -3115,7 +3223,7 @@ class Contact
* @param array $urls
* @return array result "count", "added" and "updated"
*/
public static function addByUrls(array $urls)
public static function addByUrls(array $urls): array
{
$added = 0;
$updated = 0;
@ -3148,7 +3256,7 @@ class Contact
* @return array The profile array
* @throws Exception
*/
public static function getRandomContact()
public static function getRandomContact(): array
{
$contact = DBA::selectFirst('contact', ['id', 'network', 'url', 'uid'], [
"`uid` = ? AND `network` = ? AND NOT `failed` AND `last-item` > ?",

View file

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

View file

@ -174,7 +174,7 @@ class Relation
* @param array $rel
* @return array contact list
*/
private static function getContacts(int $uid, array $rel)
private static function getContacts(int $uid, array $rel): array
{
$list = [];
$profile = Profile::getByUID($uid);
@ -182,8 +182,15 @@ class Relation
return $list;
}
$condition = ['rel' => $rel, 'uid' => $uid, 'self' => false, 'deleted' => false,
'hidden' => false, 'archive' => false, 'pending' => false];
$condition = [
'rel' => $rel,
'uid' => $uid,
'self' => false,
'deleted' => false,
'hidden' => false,
'archive' => false,
'pending' => false,
];
$condition = DBA::mergeConditions($condition, ["`url` IN (SELECT `url` FROM `apcontact`)"]);
$contacts = DBA::select('contact', ['url'], $condition);
while ($contact = DBA::fetch($contacts)) {
@ -201,7 +208,7 @@ class Relation
* @param array $contact Contact array
* @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');
@ -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 $limit optional, default 80
* @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);
$totallimit = $start + $limit;
@ -272,20 +281,25 @@ class Relation
// 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.
$results = DBA::select('contact', [],
["`id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` IN
$results = DBA::select('contact', [], ["`id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` IN
(SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ?)
AND NOT `cid` IN (SELECT `id` FROM `contact` WHERE `uid` = ? AND `nurl` IN
(SELECT `nurl` FROM `contact` WHERE `uid` = ? AND `rel` IN (?, ?))))
AND NOT `hidden` AND `network` IN (?, ?, ?, ?)",
$cid, 0, $uid, Contact::FRIEND, Contact::SHARING,
Protocol::ACTIVITYPUB, Protocol::DFRN, $diaspora, $ostatus],
['order' => ['last-item' => true], 'limit' => $totallimit]
$cid,
0,
$uid, Contact::FRIEND, Contact::SHARING,
Protocol::ACTIVITYPUB, Protocol::DFRN, $diaspora, $ostatus,
], [
'order' => ['last-item' => true],
'limit' => $totallimit,
]
);
while ($contact = DBA::fetch($results)) {
$contacts[$contact['id']] = $contact;
}
DBA::close($results);
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
* @throws Exception
*/
public static function countFollows(int $cid, array $condition = [])
public static function countFollows(int $cid, array $condition = []): int
{
$condition = DBA::mergeConditions($condition,
['`id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`)',
$cid]
);
$condition = DBA::mergeConditions($condition, [
'`id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`)',
$cid,
]);
return DI::dba()->count('contact', $condition);
}
@ -556,7 +570,7 @@ class Relation
* @param int $count
* @param int $offset
* @param bool $shuffle
* @return array
* @return array|bool Array on success, false on failure
* @throws Exception
*/
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
* @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,
['`id` IN (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ? AND `follows`)
@ -601,7 +615,7 @@ class Relation
* @param int $count
* @param int $offset
* @param bool $shuffle
* @return array
* @return array|bool Array on success, false on failure
* @throws Exception
*/
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
* @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,
["`id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ? AND `follows`)
@ -646,7 +660,7 @@ class Relation
* @param int $count
* @param int $offset
* @param bool $shuffle
* @return array
* @return array|bool Array on success, false on failure
* @throws Exception
*/
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
*
* @param array $fields
* @param array $condition
* @return void
* @throws PDOException
* @throws Exception
* @param array $fields
* @param array $condition
* @return void
* @throws PDOException
* @throws Exception
*/
public static function updateByContactUpdate(array $fields, array $condition)
{
@ -106,7 +106,7 @@ class User
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 $uid User ID
* @param boolean $blocked Is the contact blocked or unblocked?
* @return void
* @throws \Exception
*/
public static function setBlocked($cid, $uid, $blocked)
public static function setBlocked(int $cid, int $uid, bool $blocked)
{
$cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) {
@ -170,7 +171,7 @@ class User
* @return boolean is the contact id blocked for the given user?
* @throws \Exception
*/
public static function isBlocked($cid, $uid)
public static function isBlocked(int $cid, int $uid): bool
{
$cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) {
@ -208,9 +209,10 @@ class User
* @param int $cid Either public contact id or user's contact id
* @param int $uid User ID
* @param boolean $ignored Is the contact ignored or unignored?
* @return void
* @throws \Exception
*/
public static function setIgnored($cid, $uid, $ignored)
public static function setIgnored(int $cid, int $uid, bool $ignored)
{
$cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) {
@ -229,11 +231,10 @@ class User
*
* @param int $cid Either public contact id or user's contact id
* @param int $uid User ID
*
* @return boolean is the contact id ignored for the given user?
* @throws \Exception
*/
public static function isIgnored($cid, $uid)
public static function isIgnored(int $cid, int $uid): bool
{
$cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) {
@ -271,9 +272,10 @@ class User
* @param int $cid Either public contact id or user's contact id
* @param int $uid User ID
* @param boolean $collapsed are the contact's posts collapsed or uncollapsed?
* @return void
* @throws \Exception
*/
public static function setCollapsed($cid, $uid, $collapsed)
public static function setCollapsed(int $cid, int $uid, bool $collapsed)
{
$cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) {
@ -288,16 +290,15 @@ class User
*
* @param int $cid Either public contact id or user's contact id
* @param int $uid User ID
*
* @return boolean is the contact id blocked for the given user?
* @throws HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
public static function isCollapsed($cid, $uid)
public static function isCollapsed(int $cid, int $uid): bool
{
$cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) {
return;
return false;
}
$collapsed = false;
@ -318,9 +319,10 @@ class User
* @param int $cid Either public contact id or user's contact id
* @param int $uid User ID
* @param boolean $blocked Is the user blocked or unblocked by the contact?
* @return void
* @throws \Exception
*/
public static function setIsBlocked($cid, $uid, $blocked)
public static function setIsBlocked(int $cid, int $uid, bool $blocked)
{
$cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) {
@ -335,11 +337,10 @@ class User
*
* @param int $cid Either public contact id or user's contact id
* @param int $uid User ID
*
* @return boolean Is the user blocked or unblocked by the contact?
* @throws \Exception
*/
public static function isIsBlocked($cid, $uid)
public static function isIsBlocked(int $cid, int $uid): bool
{
$cdata = Contact::getPublicAndUserContactID($cid, $uid);
if (empty($cdata)) {

View file

@ -62,7 +62,7 @@ class Conversation
*/
const RELAY = 3;
public static function getByItemUri($item_uri)
public static function getByItemUri(string $item_uri)
{
return DBA::selectFirst('conversation', [], ['item-uri' => $item_uri]);
}
@ -74,7 +74,7 @@ class Conversation
* @return array Item array with removed conversation data
* @throws \Exception
*/
public static function insert(array $arr)
public static function insert(array $arr): array
{
if (in_array(($arr['network'] ?? '') ?: Protocol::PHANTOM,
[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
{
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)) {
return '';
@ -127,7 +127,7 @@ class Event
* @param array $event Array which contains the event data.
* @return string The event as a bbcode formatted string.
*/
private static function getBBCode(array $event)
private static function getBBCode(array $event): string
{
$o = '';
@ -157,11 +157,10 @@ class Event
/**
* Extract bbcode formatted event data from a string.
*
* @params: string $s The string which should be parsed for event data.
* @param $text
* @param string $text The string which should be parsed for event data.
* @return array The array with the event information.
*/
public static function fromBBCode($text)
public static function fromBBCode(string $text): array
{
$ev = [];
@ -195,13 +194,13 @@ class Event
return $ev;
}
public static function sortByDate($event_list)
public static function sortByDate(array $event_list): array
{
usort($event_list, ['self', 'compareDatesCallback']);
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_b = DateTimeFormat::local($event_b['start']);
@ -223,7 +222,7 @@ class Event
* @return void
* @throws \Exception
*/
public static function delete($event_id)
public static function delete(int $event_id)
{
if ($event_id == 0) {
return;
@ -242,7 +241,7 @@ class Event
* @return int The new event id.
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public static function store($arr)
public static function store(array $arr): int
{
$event = [];
$event['id'] = intval($arr['id'] ?? 0);
@ -317,7 +316,7 @@ class Event
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)) {
return $item;
@ -374,7 +373,7 @@ class Event
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)) {
return $item;
@ -404,7 +403,7 @@ class Event
* @return array Array with translations strings.
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public static function getStrings()
public static function getStrings(): array
{
// First day of the week (0 = Sunday).
$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.
*/
private static function removeDuplicates(array $dates)
private static function removeDuplicates(array $dates): array
{
$dates2 = [];
@ -500,7 +499,7 @@ class Event
* @return array Query result
* @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 = [];
@ -536,7 +535,7 @@ class Event
* @return array Query results.
* @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 = [];
@ -570,7 +569,7 @@ class Event
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
public static function prepareListForTemplate(array $event_result)
public static function prepareListForTemplate(array $event_result): array
{
$event_list = [];
@ -651,12 +650,12 @@ class Event
* @param array $events Query result for events.
* @param string $format The output format (ical/csv).
*
* @param $timezone
* @param string $timezone Timezone (missing parameter!)
* @return string Content according to selected export format.
*
* @todo Implement timezone support
*/
private static function formatListForExport(array $events, $format)
private static function formatListForExport(array $events, string $format): string
{
$o = '';
@ -757,7 +756,7 @@ class Event
* @return array Query results.
* @throws \Exception
*/
private static function getListByUserId($uid = 0)
private static function getListByUserId(int $uid = 0): array
{
$return = [];
@ -797,7 +796,7 @@ class Event
* @throws \Exception
* @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;
@ -845,7 +844,8 @@ class Event
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
public static function getItemHTML(array $item) {
public static function getItemHTML(array $item): string
{
$same_date = false;
$finish = false;
@ -933,10 +933,11 @@ class Event
* @return array The array with the location data.
* 'name' => The name 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
*/
private static function locationToArray($s = '') {
private static function locationToArray(string $s = ''): array
{
if ($s == '') {
return [];
}
@ -981,7 +982,7 @@ class Event
* @return bool
* @throws \Exception
*/
public static function createBirthday($contact, $birthday)
public static function createBirthday(array $contact, string $birthday): bool
{
// Check for duplicates
$condition = [
@ -1011,8 +1012,7 @@ class Event
'type' => 'birthday',
];
self::store($values);
return true;
// Check if self::store() was success
return (self::store($values) > 0);
}
}

View file

@ -40,7 +40,7 @@ class FContact
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @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]);
if (!DBA::isResult($person)) {
@ -90,7 +90,7 @@ class FContact
* @param array $arr The fcontact data
* @throws \Exception
*/
public static function updateFromProbeArray($arr)
public static function updateFromProbeArray(array $arr)
{
$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*
* 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
*/
public static function getUrlByGuid($fcontact_guid)
public static function getUrlByGuid(string $fcontact_guid)
{
Logger::info('fcontact', ['guid' => $fcontact_guid]);

View file

@ -35,10 +35,9 @@ class FileTag
* URL encode <, >, left and right brackets
*
* @param string $s String to be URL encoded.
*
* @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);
}
@ -47,10 +46,9 @@ class FileTag
* URL decode <, >, left and right brackets
*
* @param string $s The URL encoded string to be decoded
*
* @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);
}
@ -62,10 +60,9 @@ class FileTag
*
* @param array $array A list of tags.
* @param string $type Optional file type.
*
* @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 = '';
if ($type == 'file') {
@ -92,10 +89,9 @@ class FileTag
*
* @param string $file File tags
* @param string $type Optional file type.
*
* @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 = [];
$return = [];

View file

@ -30,6 +30,7 @@ use Friendica\Core\System;
use Friendica\Core\Worker;
use Friendica\Database\Database;
use Friendica\Database\DBA;
use Friendica\Database\DBStructure;
use Friendica\DI;
use Friendica\Module\Register;
use Friendica\Network\HTTPClient\Client\HttpClientAccept;
@ -96,7 +97,7 @@ class GServer
*
* @param string $url
* @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)
{
@ -156,7 +157,7 @@ class GServer
*
* @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 == '') {
$contact = Contact::getByURL($profile, null, ['baseurl']);
@ -172,7 +173,7 @@ class GServer
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
if ($success) {
@ -231,7 +232,7 @@ class GServer
*
* @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);
if ($server_url == '') {
@ -243,7 +244,7 @@ class GServer
if ($gserver['created'] <= DBA::NULL_DATETIME) {
$fields = ['created' => DateTimeFormat::utcNow()];
$condition = ['nurl' => Strings::normaliseLink($server_url)];
DBA::update('gserver', $fields, $condition);
self::update($fields, $condition);
}
if (!$force && (strtotime($gserver['next_contact']) > time())) {
@ -268,7 +269,7 @@ class GServer
$gserver = DBA::selectFirst('gserver', [], ['nurl' => Strings::normaliseLink($url)]);
if (DBA::isResult($gserver)) {
$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],
['nurl' => Strings::normaliseLink($url)]);
Logger::info('Set failed status for existing server', ['url' => $url]);
@ -286,7 +287,7 @@ class GServer
* @param string $url
* @return string cleaned URL
*/
public static function cleanURL(string $url)
public static function cleanURL(string $url): string
{
$url = trim($url, '/');
$url = str_replace('/index.php', '', $url);
@ -305,7 +306,7 @@ class GServer
* @param string $url
* @return string base URL
*/
private static function getBaseURL(string $url)
private static function getBaseURL(string $url): string
{
$urlparts = parse_url(self::cleanURL($url));
unset($urlparts['path']);
@ -322,7 +323,7 @@ class GServer
*
* @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]);
$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 ($url != $original_url) {
/// @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)]);
}
@ -535,13 +536,13 @@ class GServer
$serverdata['last_contact'] = DateTimeFormat::utcNow();
$serverdata['failed'] = false;
$gserver = DBA::selectFirst('gserver', ['network'], ['nurl' => Strings::normaliseLink($url)]);
$gserver = DBA::selectFirst('gserver', ['network'], ['nurl' => $serverdata['nurl']]);
if (!DBA::isResult($gserver)) {
$serverdata['created'] = DateTimeFormat::utcNow();
$ret = DBA::insert('gserver', $serverdata);
$id = DBA::lastInsertId();
} else {
$ret = DBA::update('gserver', $serverdata, ['nurl' => $serverdata['nurl']]);
$ret = self::update($serverdata, ['nurl' => $serverdata['nurl']]);
$gserver = DBA::selectFirst('gserver', ['id'], ['nurl' => $serverdata['nurl']]);
if (DBA::isResult($gserver)) {
$id = $gserver['id'];
@ -555,14 +556,14 @@ class GServer
$max_users = max($apcontacts, $contacts);
if ($max_users > $serverdata['registered-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'])) {
$contacts = DBA::count('contact', ["`uid` = ? AND `gsid` = ? AND NOT `failed` AND `last-item` > ?", 0, $id, DateTimeFormat::utc('now - 30 days')]);
if ($contacts > 0) {
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')]);
if ($contacts > 0) {
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
*
* @param string $server_url address of the server
* @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function discoverRelay(string $server_url)
@ -618,7 +620,7 @@ class GServer
if (($gserver['relay-subscribe'] != $data['subscribe']) || ($gserver['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']]);
@ -682,10 +684,9 @@ class GServer
* Fetch server data from '/statistics.json' on the given server
*
* @param string $url URL of the given server
*
* @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);
if (!$curlResult->isSuccess()) {
@ -758,7 +759,7 @@ class GServer
* @return array Server data
* @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()) {
return [];
@ -811,7 +812,7 @@ class GServer
* @return array Server data
* @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);
if (!$curlResult->isSuccess()) {
@ -904,7 +905,7 @@ class GServer
* @return array Server data
* @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);
if (!$curlResult->isSuccess()) {
@ -917,8 +918,11 @@ class GServer
return [];
}
$server = ['detection-method' => self::DETECT_NODEINFO_2,
'register_policy' => Register::CLOSED];
$server = [
'detection-method' => self::DETECT_NODEINFO_2,
'register_policy' => Register::CLOSED,
'platform' => 'unknown',
];
if (!empty($nodeinfo['openRegistrations'])) {
$server['register_policy'] = Register::OPEN;
@ -1001,10 +1005,9 @@ class GServer
*
* @param string $url URL of the given server
* @param array $serverdata array with 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);
if (!$curlResult->isSuccess()) {
@ -1085,10 +1088,9 @@ class GServer
* Checks if the server contains a valid host meta file
*
* @param string $url URL of the given server
*
* @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');
$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 array $serverdata array with server data
*
* @return array server data
*/
private static function detectNetworkViaContacts(string $url, array $serverdata)
private static function detectNetworkViaContacts(string $url, array $serverdata): array
{
$contacts = [];
@ -1176,10 +1177,9 @@ class GServer
*
* @param string $url URL of the given server
* @param array $serverdata array with 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'] = '';
@ -1208,10 +1208,9 @@ class GServer
*
* @param string $url URL of the given server
* @param array $serverdata array with 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);
if (!$curlResult->isSuccess()) {
@ -1238,7 +1237,7 @@ class GServer
*
* @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);
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) {
@ -1282,10 +1281,9 @@ class GServer
*
* @param string $url URL of the given server
* @param array $serverdata array with 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);
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) {
@ -1310,7 +1308,15 @@ class GServer
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);
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) {
return $serverdata;
@ -1346,10 +1352,9 @@ class GServer
*
* @param string $url URL of the given server
* @param array $serverdata array with 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)]);
if (empty($gserver)) {
@ -1374,10 +1379,9 @@ class GServer
*
* @param string $url URL of the given server
* @param array $serverdata array with 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);
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) {
@ -1439,10 +1443,9 @@ class GServer
*
* @param string $url URL of the given server
* @param array $serverdata array with 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);
if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) {
@ -1517,10 +1520,9 @@ class GServer
* Converts input value to a boolean value
*
* @param string|integer $val
*
* @return boolean
*/
private static function toBoolean($val)
private static function toBoolean($val): bool
{
if (($val == 'true') || ($val == 1)) {
return true;
@ -1536,10 +1538,9 @@ class GServer
*
* @param string $url URL of the given server
* @param array $serverdata array with 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);
if (!$curlResult->isSuccess()) {
@ -1549,7 +1550,6 @@ class GServer
$data = json_decode($curlResult->getBody(), true);
if (empty($data['links'])) {
return $serverdata;
}
// 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 array $serverdata array with 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
$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 array $serverdata array with 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.
// Because of this me must not use ACCEPT_JSON here.
@ -1717,10 +1715,9 @@ class GServer
* @param object $curlResult result of curl execution
* @param array $serverdata array with server data
* @param string $url Server URL
*
* @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())) {
return $serverdata;
@ -1859,7 +1856,7 @@ class GServer
*
* @return array server data
*/
private static function analyseRootHeader($curlResult, array $serverdata)
private static function analyseRootHeader($curlResult, array $serverdata): array
{
if ($curlResult->getHeader('server') == 'Mastodon') {
$serverdata['platform'] = 'mastodon';
@ -1926,7 +1923,7 @@ class GServer
Worker::add(PRIORITY_LOW, 'UpdateServerDirectory', $gserver);
$fields = ['last_poco_query' => DateTimeFormat::utcNow()];
DBA::update('gserver', $fields, ['nurl' => $gserver['nurl']]);
self::update($fields, ['nurl' => $gserver['nurl']]);
if (--$no_of_queries == 0) {
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)]);
DBA::update('gserver', ['protocol' => $protocol], ['id' => $gsid]);
self::update(['protocol' => $protocol], ['id' => $gsid]);
}
/**
* Fetch the protocol of the given server
*
* @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
*/
public static function getProtocol(int $gsid)
public static function getProtocol(int $gsid): ?int
{
if (empty($gsid)) {
return null;
@ -2067,4 +2064,19 @@ class GServer
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 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];
@ -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
* @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];
if (isset($uid)) {
if (!is_null($uid)) {
$condition = [
'uid' => $uid
];
@ -73,12 +83,12 @@ class Group
*
* Note: If we found a deleted group with the same name, we restore it
*
* @param int $uid
* @param string $name
* @return boolean
* @param int $uid User id to create group for
* @param string $name Name of group
* @return int|boolean Id of newly created group or false on error
* @throws \Exception
*/
public static function create($uid, $name)
public static function create(int $uid, string $name)
{
$return = false;
if (!empty($uid) && !empty($name)) {
@ -114,7 +124,7 @@ class Group
* @return bool Was the update successful?
* @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]);
}
@ -122,11 +132,11 @@ class Group
/**
* Get a list of group ids a contact belongs to
*
* @param int $cid
* @return array
* @param int $cid Contact id
* @return array Group ids
* @throws \Exception
*/
public static function getIdsByContactId($cid)
public static function getIdsByContactId(int $cid): array
{
$return = [];
@ -185,12 +195,12 @@ class Group
*
* Returns false if no group has been found.
*
* @param int $uid
* @param string $name
* @return int|boolean
* @param int $uid User id
* @param string $name Group name
* @return int|boolean Groups' id number or false on error
* @throws \Exception
*/
public static function getIdByName($uid, $name)
public static function getIdByName(int $uid, string $name)
{
if (!$uid || !strlen($name)) {
return false;
@ -211,7 +221,7 @@ class Group
* @return boolean
* @throws \Exception
*/
public static function remove($gid)
public static function remove(int $gid): bool
{
if (!$gid) {
return false;
@ -314,13 +324,14 @@ class Group
* Adds contacts to a group
*
* @param int $gid
* @param array $contacts
* @param array $contacts Array with contact ids
* @return void
* @throws \Exception
*/
public static function addMembers(int $gid, array $contacts)
{
if (!$gid || !$contacts) {
return false;
return;
}
// @TODO Backward compatibility with user contacts, remove by version 2022.03
@ -342,8 +353,9 @@ class Group
/**
* Removes contacts from a group
*
* @param int $gid
* @param array $contacts
* @param int $gid Group id
* @param array $contacts Contact ids
* @return bool
* @throws \Exception
*/
public static function removeMembers(int $gid, array $contacts)
@ -369,19 +381,20 @@ class Group
$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
*
* @param int $uid
* @param array $group_ids
* @param boolean $check_dead
* @param int $uid User id
* @param array $group_ids Groups ids
* @param boolean $check_dead Whether check "dead" records (?)
* @return array
* @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)) {
return [];
@ -454,13 +467,13 @@ class Group
/**
* Returns a templated group selection list
*
* @param int $uid
* @param int $uid User id
* @param int $gid An optional pre-selected group
* @param string $label An optional label of the list
* @return string
* @throws \Exception
*/
public static function displayGroupSelection($uid, $gid = 0, $label = '')
public static function displayGroupSelection(int $uid, int $gid = 0, string $label = ''): string
{
$display_groups = [
[
@ -502,12 +515,12 @@ class Group
* 'standard' => include link 'Edit groups'
* 'extended' => include link 'Create new group'
* 'full' => include link 'Create new group' and provide for each group a link to edit this group
* @param string $group_id
* @param int $cid
* @return string
* @param string|int $group_id Distinct group id or 'everyone'
* @param int $cid Contact id
* @return string Sidebar widget HTML code
* @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()) {
return '';
@ -589,7 +602,7 @@ class Group
* @param integer $id Contact ID
* @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]);
$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
*
* @param integer $id Contact ID
* @return void
*/
public static function updateMembersForForum(int $id)
{

View file

@ -96,8 +96,8 @@ class Item
'event-created', 'event-edited', 'event-start', 'event-finish',
'event-summary', 'event-desc', 'event-location', 'event-type',
'event-nofinish', 'event-ignore', 'event-id',
"question-id", "question-multiple", "question-voters", "question-end-time",
"has-categories", "has-media",
'question-id', 'question-multiple', 'question-voters', 'question-end-time',
'has-categories', 'has-media',
'delivery_queue_count', 'delivery_queue_done', 'delivery_queue_failed'
];
@ -226,7 +226,7 @@ class Item
foreach ($notify_items as $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;
@ -237,9 +237,10 @@ class Item
*
* @param array $condition The condition for finding the item entries
* @param integer $priority Priority for the notification
* @return void
* @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);
while ($item = Post::fetch($items)) {
@ -253,9 +254,10 @@ class Item
*
* @param array $condition The condition for finding the item entries
* @param integer $uid User who wants to delete this item
* @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public static function deleteForUser($condition, $uid)
public static function deleteForUser(array $condition, int $uid)
{
if ($uid == 0) {
return;
@ -282,11 +284,10 @@ class Item
*
* @param integer $item_id
* @param integer $priority Priority for the notification
*
* @return boolean success
* @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()]);
// locate item to be deleted
@ -331,7 +332,7 @@ class Item
// If item has attachments, drop them
$attachments = Post\Media::getByURIId($item['uri-id'], [Post\Media::DOCUMENT]);
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']]);
}
}
@ -360,7 +361,7 @@ class Item
// send the notification upstream/downstream
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) {
Post\User::update($item['uri-id'], $item['uid'], ['hidden' => true]);
@ -372,7 +373,14 @@ class Item
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'])) {
return trim($item['guid']);
@ -425,7 +433,13 @@ class Item
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']])) {
return $item['contact-id'];
@ -451,17 +465,17 @@ class Item
* @param array $item The item fields that are to be inserted
* @throws \Exception
*/
private static function spool($orig_item)
private static function spool(array $item)
{
// Now we store the data in the spool directory
// We use "microtime" to keep the arrival order and "mt_rand" to avoid duplicates
$file = 'item-' . round(microtime(true) * 10000) . '-' . mt_rand() . '.msg';
$spoolpath = System::getSpoolPath();
if ($spoolpath != "") {
if ($spoolpath != '') {
$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]);
}
}
@ -469,10 +483,10 @@ class Item
/**
* Check if the item array is a duplicate
*
* @param array $item
* @param array $item Item record
* @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
$condition = ['guid' => $item['guid'], 'network' => $item['network'], 'uid' => $item['uid']];
@ -521,10 +535,10 @@ class Item
/**
* Check if the item array is valid
*
* @param array $item
* @param array $item Item record
* @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
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
*
* @param array $item
* @param array $item Item record
* @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
$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
*
* @param array $item
* @return integer item id
* @param array $item Item record
* @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)) {
$condition = ["`uri-id` = ? AND `uid` = ? AND `network` IN (?, ?, ?, ?)",
$item['uri-id'], $item['uid'],
Protocol::ACTIVITYPUB, Protocol::DIASPORA, Protocol::DFRN, Protocol::OSTATUS];
$condition = ['`uri-id` = ? AND `uid` = ? AND `network` IN (?, ?, ?, ?)',
$item['uri-id'],
$item['uid'],
Protocol::ACTIVITYPUB,
Protocol::DIASPORA,
Protocol::DFRN,
Protocol::OSTATUS
];
$existing = Post::selectFirst(['id', 'network'], $condition);
if (DBA::isResult($existing)) {
// 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'],
'uid' => $item['uid'],
'network' => $item['network'],
'existing_id' => $existing["id"],
'existing_network' => $existing["network"]
'existing_id' => $existing['id'],
'existing_network' => $existing['network']
]);
}
return $existing["id"];
return $existing['id'];
}
}
return 0;
@ -658,7 +677,7 @@ class Item
* @return array item array with parent data
* @throws \Exception
*/
private static function getTopLevelParent(array $item)
private static function getTopLevelParent(array $item): array
{
$fields = ['uid', 'uri', 'parent-uri', 'id', 'deleted',
'uri-id', 'parent-uri-id',
@ -709,7 +728,7 @@ class Item
* @param array $item
* @return integer gravity
*/
private static function getGravity(array $item)
private static function getGravity(array $item): int
{
$activity = DI::activity();
@ -724,11 +743,20 @@ class Item
} elseif ($activity->match($item['verb'], Activity::ANNOUNCE)) {
return GRAVITY_ACTIVITY;
}
Logger::info('Unknown gravity for verb', ['verb' => $item['verb']]);
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;
@ -869,7 +897,7 @@ class Item
Contact::checkAvatarCache($item['owner-id']);
// 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]) &&
empty($item['origin']) &&self::isTooOld($item)) {
@ -944,8 +972,8 @@ class Item
$item['thr-parent-id'] = ItemURI::getIdByURI($item['thr-parent']);
// Is this item available in the global items (with uid=0)?
if ($item["uid"] == 0) {
$item["global"] = true;
if ($item['uid'] == 0) {
$item['global'] = true;
// Set the global flag on all items if this was a global item entry
Post::update(['global' => true], ['uri-id' => $item['uri-id']]);
@ -954,8 +982,8 @@ class Item
}
// ACL settings
if (!empty($item["allow_cid"] . $item["allow_gid"] . $item["deny_cid"] . $item["deny_gid"])) {
$item["private"] = self::PRIVATE;
if (!empty($item['allow_cid'] . $item['allow_gid'] . $item['deny_cid'] . $item['deny_gid'])) {
$item['private'] = self::PRIVATE;
}
if ($notify && $post_local) {
@ -1323,7 +1351,7 @@ class Item
* @param string $signed_text Original text (for Diaspora signatures), JSON encoded.
* @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];
$parent = Post::selectFirst(['owner-id'], $condition);
@ -1417,7 +1445,7 @@ class Item
* @param integer $source_uid User id of the source post
* @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) {
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
* @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 (!empty($item['event-id'])) {
@ -1613,7 +1641,7 @@ class Item
* @param integer $itemid Item ID that should be added
* @throws \Exception
*/
private static function addShadow($itemid)
private static function addShadow(int $itemid)
{
$fields = ['uid', 'private', 'visible', 'deleted', 'network', 'uri-id'];
$condition = ['id' => $itemid, 'gravity' => GRAVITY_PARENT];
@ -1676,7 +1704,7 @@ class Item
* @param integer $itemid Item ID that should be added
* @throws \Exception
*/
private static function addShadowPost($itemid)
private static function addShadowPost(int $itemid)
{
$item = Post::selectFirst(self::ITEM_FIELDLIST, ['id' => $itemid]);
if (!DBA::isResult($item)) {
@ -1740,7 +1768,7 @@ class Item
* @return string detected language
* @throws \Text_LanguageDetect_Exception
*/
private static function getLanguage(array $item)
private static function getLanguage(array $item): string
{
if (!empty($item['language'])) {
return $item['language'];
@ -1784,7 +1812,7 @@ class Item
return '';
}
public static function getLanguageMessage(array $item)
public static function getLanguageMessage(array $item): string
{
$iso639 = new \Matriphe\ISO639\ISO639;
@ -1802,24 +1830,24 @@ class Item
* Posts that are created on this system are using System::createUUID.
* Received ActivityPub posts are using Processor::getGUIDByURL.
*
* @param string $uri uri of an item entry
* @param string $host hostname for the GUID prefix
* @return string unique guid
* @param string $uri uri of an item entry
* @param string|null $host hostname for the GUID prefix
* @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
// We have to avoid that different routines could accidentally create the same value
$parsed = parse_url($uri);
// 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
$host_id = implode("/", $parsed);
$host_id = implode('/', $parsed);
// 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
* @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();
}
@ -1850,7 +1878,7 @@ class Item
* @param array $arr Contains the just posted item record
* @throws \Exception
*/
private static function updateContact($arr)
private static function updateContact(array $arr)
{
// Unarchive the author
$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) {
$tags = BBCode::getTags($body);
@ -1971,7 +1999,7 @@ class Item
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
private static function tagDeliver($uid, $item_id)
private static function tagDeliver(int $uid, int $item_id): bool
{
$mention = false;
@ -2066,7 +2094,7 @@ class Item
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']) {
return false;
@ -2160,7 +2188,7 @@ class Item
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @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')) {
return $s;
@ -2254,13 +2282,14 @@ class Item
return $new_body;
}
private static function hasPermissions($obj)
private static function hasPermissions(array $obj)
{
return !empty($obj['allow_cid']) || !empty($obj['allow_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.
if (($obj1['allow_cid'] == $obj2['allow_cid'])
@ -2288,7 +2317,7 @@ class Item
* @return array
* @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();
@ -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");
}
public static function firstPostDate($uid, $wall = false)
public static function firstPostDate(int $uid, bool $wall = false)
{
$user = User::getById($uid, ['register_date']);
if (empty($user)) {
@ -2417,7 +2446,7 @@ class Item
* array $arr
* '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)) {
return false;
@ -2611,7 +2640,7 @@ class Item
* @param integer $owner_id User ID for which the permissions should be fetched
* @return array condition
*/
public static function getPermissionsConditionArrayByUserId(int $owner_id)
public static function getPermissionsConditionArrayByUserId(int $owner_id): array
{
$local_user = local_user();
$remote_user = Session::getRemoteContactID($owner_id);
@ -2643,7 +2672,7 @@ class Item
* @param string $table
* @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();
$remote_user = Session::getRemoteContactID($owner_id);
@ -2691,7 +2720,7 @@ class Item
* @param \Friendica\Core\L10n $l10n
* @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'])) {
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.
* If attach is true, also add icons for item attachments.
*
* @param array $item
* @param boolean $attach
* @param boolean $is_preview
* @param boolean $only_cache
* @param array $item Record from item table
* @param boolean $attach If true, add icons for item attachments as well
* @param boolean $is_preview Whether this is a preview
* @param boolean $only_cache Whether only cached HTML should be updated
* @return string item body html
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @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_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();
Hook::callAll('prepare_body_init', $item);
@ -2802,7 +2831,8 @@ class Item
$shared_uri_id = 0;
$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'] = preg_replace("/\s*\[attachment .*?\].*?\[\/attachment\]\s*/ism", "\n", $item['body']);
@ -2811,7 +2841,7 @@ class Item
$s = $item["rendered-html"];
if ($only_cache) {
return;
return '';
}
// Compile eventual content filter reasons
@ -2891,7 +2921,7 @@ class Item
* @param int $type
* @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
$urlparts = parse_url($url);
@ -2924,7 +2954,7 @@ class Item
* @param string $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');
@ -2955,7 +2985,7 @@ class Item
* @param string $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');
$leading = '';
@ -3047,7 +3077,7 @@ class Item
* @param array $ignore_links A list of URLs to ignore
* @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');
// Don't show a preview when there is a visual attachment (audio or video)
@ -3161,7 +3191,7 @@ class Item
* @param string $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');
$trailing = '';
@ -3193,7 +3223,7 @@ class Item
return $content;
}
private static function addQuestions(array $item, string $content)
private static function addQuestions(array $item, string $content): string
{
DI::profiler()->startRecording('rendering');
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)
* @throws \Exception
*/
public static function getPlink($item)
public static function getPlink(array $item)
{
if (!empty($item['plink']) && Network::isValidHttpUrl($item['plink'])) {
$plink = $item['plink'];
@ -3291,7 +3321,7 @@ class Item
*
* @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) {
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
*/
public static function searchByLink($uri, $uid = 0)
public static function searchByLink(string $uri, int $uid = 0): int
{
$ssl_uri = str_replace('http://', 'https://', $uri);
$uris = [$uri, $ssl_uri, Strings::normaliseLink($uri)];
@ -3334,7 +3364,7 @@ class Item
*
* @return string URI
*/
public static function getURIByLink(string $uri)
public static function getURIByLink(string $uri): string
{
$ssl_uri = str_replace('http://', 'https://', $uri);
$uris = [$uri, $ssl_uri, Strings::normaliseLink($uri)];
@ -3360,7 +3390,7 @@ class Item
*
* @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]);
$item_id = self::searchByLink($uri, $uid);
@ -3406,7 +3436,7 @@ class Item
*
* @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)) {
return [];
@ -3429,7 +3459,7 @@ class 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);
if (empty($shared)) {
@ -3490,7 +3520,7 @@ class Item
* @return bool
* @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)) {
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
* @return string body
*/
public static function improveSharedDataInBody(array $item)
public static function improveSharedDataInBody(array $item): string
{
$shared = BBCode::fetchShareAttributes($item['body']);
if (empty($shared['link'])) {

View file

@ -30,7 +30,6 @@ class ItemURI
* Insert an item-uri record and return its id
*
* @param array $fields Item-uri fields
*
* @return int|null item-uri id
* @throws \Exception
*/
@ -61,12 +60,15 @@ class ItemURI
* Searched for an id of a given uri. Adds it, if not existing yet.
*
* @param string $uri
*
* @return integer item-uri id
* @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
$uri = substr($uri, 0, 255);
@ -82,11 +84,10 @@ class ItemURI
* Searched for an id of a given guid.
*
* @param string $guid
*
* @return integer item-uri id
* @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
$guid = substr($guid, 0, 255);

View file

@ -45,7 +45,7 @@ class ParsedLogIterator implements \Iterator
private $filters = [];
/** @var string search term */
private $search = "";
private $search = '';
/**
@ -60,7 +60,7 @@ class ParsedLogIterator implements \Iterator
* @param string $filename File to open
* @return $this
*/
public function open(string $filename)
public function open(string $filename): ParsedLogIterator
{
$this->reader->open($filename);
return $this;
@ -70,7 +70,7 @@ class ParsedLogIterator implements \Iterator
* @param int $limit Max num of lines to read
* @return $this
*/
public function withLimit(int $limit)
public function withLimit(int $limit): ParsedLogIterator
{
$this->limit = $limit;
return $this;
@ -80,7 +80,7 @@ class ParsedLogIterator implements \Iterator
* @param array $filters filters per column
* @return $this
*/
public function withFilters(array $filters)
public function withFilters(array $filters): ParsedLogIterator
{
$this->filters = $filters;
return $this;
@ -90,7 +90,7 @@ class ParsedLogIterator implements \Iterator
* @param string $search string to search to filter lines
* @return $this
*/
public function withSearch(string $search)
public function withSearch(string $search): ParsedLogIterator
{
$this->search = $search;
return $this;
@ -100,18 +100,19 @@ class ParsedLogIterator implements \Iterator
* Check if parsed log line match filters.
* Always match if no filters are set.
*
* @param ParsedLogLine $parsedlogline
* @return bool
* @param ParsedLogLine $parsedlogline ParsedLogLine instance
* @return bool Wether the parse log line matches
*/
private function filter($parsedlogline)
private function filter(ParsedLogLine $parsedlogline): bool
{
$match = true;
foreach ($this->filters as $filter => $filtervalue) {
switch ($filter) {
case "level":
case 'level':
$match = $match && ($parsedlogline->level == strtoupper($filtervalue));
break;
case "context":
case 'context':
$match = $match && ($parsedlogline->context == $filtervalue);
break;
}
@ -126,9 +127,9 @@ class ParsedLogIterator implements \Iterator
* @param ParsedLogLine $parsedlogline
* @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 true;
@ -138,7 +139,6 @@ class ParsedLogIterator implements \Iterator
* Read a line from reader and parse.
* Returns null if limit is reached or the reader is invalid.
*
* @param ParsedLogLine $parsedlogline
* @return ?ParsedLogLine
*/
private function read()
@ -191,7 +191,7 @@ class ParsedLogIterator implements \Iterator
* @see ReversedFileReader::key()
* @return int
*/
public function key()
public function key(): int
{
return $this->reader->key();
}
@ -213,8 +213,8 @@ class ParsedLogIterator implements \Iterator
* @see Iterator::valid()
* @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 \ImagickException
*/
public static function insert($msg, $notification = true)
public static function insert(array $msg, bool $notification = true)
{
if (!isset($msg['reply'])) {
$msg['reply'] = DBA::exists('mail', ['parent-uri' => $msg['parent-uri']]);
@ -125,7 +125,7 @@ class Mail
* @return int
* @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();
@ -255,7 +255,7 @@ class Mail
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @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) {
return -1;

View file

@ -22,6 +22,7 @@
namespace Friendica\Model;
use Friendica\Core\Addon;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Database\DBA;
use Friendica\DI;
use stdClass;
@ -101,7 +102,7 @@ class Nodeinfo
*
* @return array with supported services
*/
public static function getServices()
public static function getServices(): array
{
$services = [
'inbound' => [],
@ -156,9 +157,19 @@ class Nodeinfo
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'))) {
$adminList = explode(',', str_replace(' ', '', $config->get('config', 'admin_email')));

View file

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

View file

@ -94,7 +94,7 @@ class Photo
$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
* @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["uid"] = $uid;
$conditions['resource-id'] = $resourceid;
$conditions['uid'] = $uid;
return self::selectToArray([], $conditions, $params);
}
@ -132,11 +132,11 @@ class Photo
* @throws \Exception
* @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["uid"] = $uid;
$conditions["scale"] = $scale;
$conditions['resource-id'] = $resourceid;
$conditions['uid'] = $uid;
$conditions['scale'] = $scale;
return self::selectFirst([], $conditions, $params);
}
@ -156,19 +156,19 @@ class Photo
*/
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)) {
return false;
}
$uid = $r["uid"];
$uid = $r['uid'];
$accessible = $uid ? (bool)DI::pConfig()->get($uid, 'system', 'accessible-photos', false) : false;
$sql_acl = Security::getPermissionsSQLByUserId($uid, $accessible);
$conditions = ["`resource-id` = ? AND `scale` <= ? " . $sql_acl, $resourceid, $scale];
$params = ["order" => ["scale" => true]];
$params = ['order' => ['scale' => true]];
$photo = self::selectFirst([], $conditions, $params);
return $photo;
@ -182,9 +182,9 @@ class Photo
* @return boolean
* @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'
*
* @return \Friendica\Object\Image
* @return \Friendica\Object\Image|null Image object or null on error
*/
public static function getImageDataForPhoto(array $photo)
{
@ -248,11 +248,11 @@ class Photo
* @return array field list
* @throws \Exception
*/
private static function getFields()
private static function getFields(): array
{
$allfields = DBStructure::definition(DI::app()->getBasePath(), false);
$fields = array_keys($allfields["photo"]["fields"]);
array_splice($fields, array_search("data", $fields), 1);
$fields = array_keys($allfields['photo']['fields']);
array_splice($fields, array_search('data', $fields), 1);
return $fields;
}
@ -265,14 +265,14 @@ class Photo
* @return array
* @throws \Exception
*/
public static function createPhotoForSystemResource($filename, $mimetype = '')
public static function createPhotoForSystemResource(string $filename, string $mimetype = ''): array
{
if (empty($mimetype)) {
$mimetype = Images::guessTypeByExtension($filename);
}
$fields = self::getFields();
$values = array_fill(0, count($fields), "");
$values = array_fill(0, count($fields), '');
$photo = array_combine($fields, $values);
$photo['backend-class'] = SystemResource::NAME;
@ -293,14 +293,14 @@ class Photo
* @return array
* @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)) {
$mimetype = Images::guessTypeByExtension($url);
}
$fields = self::getFields();
$values = array_fill(0, count($fields), "");
$values = array_fill(0, count($fields), '');
$photo = array_combine($fields, $values);
$photo['backend-class'] = ExternalResource::NAME;
@ -314,14 +314,14 @@ class Photo
/**
* 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 $cid Contact ID
* @param integer $rid Resource ID
* @param string $rid Resource ID
* @param string $filename Filename
* @param string $album Album name
* @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_gid Permissions, allowed groups. optional, default = ""
* @param string $deny_cid Permissions, denied contacts.optional, default = ""
@ -331,71 +331,71 @@ class Photo
* @return boolean True on success
* @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)) {
$guid = $photo["guid"];
$guid = $photo['guid'];
} else {
$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();
if (DBA::isResult($existing_photo)) {
$created = $existing_photo["created"];
$created = $existing_photo['created'];
}
// Get defined storage backend.
// if no storage backend, we use old "data" column in photo table.
// if is an existing photo, reuse same backend
$data = "";
$backend_ref = "";
$storage = "";
$data = '';
$backend_ref = '';
$storage = '';
try {
if (DBA::isResult($existing_photo)) {
$backend_ref = (string)$existing_photo["backend-ref"];
$storage = DI::storageManager()->getWritableStorageByName($existing_photo["backend-class"] ?? '');
$backend_ref = (string)$existing_photo['backend-ref'];
$storage = DI::storageManager()->getWritableStorageByName($existing_photo['backend-class'] ?? '');
} else {
$storage = DI::storage();
}
$backend_ref = $storage->put($Image->asString(), $backend_ref);
$backend_ref = $storage->put($image->asString(), $backend_ref);
} catch (InvalidClassStorageException $storageException) {
$data = $Image->asString();
$data = $image->asString();
}
$fields = [
"uid" => $uid,
"contact-id" => $cid,
"guid" => $guid,
"resource-id" => $rid,
"hash" => md5($Image->asString()),
"created" => $created,
"edited" => DateTimeFormat::utcNow(),
"filename" => basename($filename),
"type" => $Image->getType(),
"album" => $album,
"height" => $Image->getHeight(),
"width" => $Image->getWidth(),
"datasize" => strlen($Image->asString()),
"data" => $data,
"scale" => $scale,
"photo-type" => $type,
"profile" => false,
"allow_cid" => $allow_cid,
"allow_gid" => $allow_gid,
"deny_cid" => $deny_cid,
"deny_gid" => $deny_gid,
"desc" => $desc,
"backend-class" => (string)$storage,
"backend-ref" => $backend_ref
'uid' => $uid,
'contact-id' => $cid,
'guid' => $guid,
'resource-id' => $rid,
'hash' => md5($image->asString()),
'created' => $created,
'edited' => DateTimeFormat::utcNow(),
'filename' => basename($filename),
'type' => $image->getType(),
'album' => $album,
'height' => $image->getHeight(),
'width' => $image->getWidth(),
'datasize' => strlen($image->asString()),
'data' => $data,
'scale' => $scale,
'photo-type' => $type,
'profile' => false,
'allow_cid' => $allow_cid,
'allow_gid' => $allow_gid,
'deny_cid' => $deny_cid,
'deny_gid' => $deny_gid,
'desc' => $desc,
'backend-class' => (string)$storage,
'backend-ref' => $backend_ref
];
if (DBA::isResult($existing_photo)) {
$r = DBA::update("photo", $fields, ["id" => $existing_photo["id"]]);
$r = DBA::update('photo', $fields, ['id' => $existing_photo['id']]);
} else {
$r = DBA::insert("photo", $fields);
$r = DBA::insert('photo', $fields);
}
return $r;
@ -413,7 +413,7 @@ class Photo
* @throws \Exception
* @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
$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->delete($photo['backend-ref'] ?? '');
// Delete the photos after they had been deleted successfully
DBA::delete("photo", ['id' => $photo['id']]);
DBA::delete('photo', ['id' => $photo['id']]);
} catch (InvalidClassStorageException $storageException) {
DI::logger()->debug('Storage class not found.', ['conditions' => $conditions, 'exception' => $storageException]);
} catch (ReferenceStorageException $referenceStorageException) {
@ -433,34 +433,34 @@ class Photo
DBA::close($photos);
return DBA::delete("photo", $conditions, $options);
return DBA::delete('photo', $conditions, $options);
}
/**
* Update a photo
*
* @param array $fields Contains the fields that are updated
* @param array $conditions Condition array with the key values
* @param Image $img 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 $fields Contains the fields that are updated
* @param array $conditions Condition array with the key values
* @param Image $image Image to update. Optional, default null.
* @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?
*
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @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
$photos = self::selectToArray(['backend-class', 'backend-ref'], $conditions);
foreach($photos as $photo) {
try {
$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) {
$fields["data"] = $img->asString();
$fields['data'] = $image->asString();
}
}
$fields['updated'] = DateTimeFormat::utcNow();
@ -468,7 +468,7 @@ class Photo
$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 $cid contact id
* @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 \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 = "";
$micro = "";
$thumb = '';
$micro = '';
$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'])) {
$resource_id = $photo["resource-id"];
$resource_id = $photo['resource-id'];
} else {
$resource_id = self::newResource();
}
@ -507,66 +507,66 @@ class Photo
$type = '';
}
if ($quit_on_error && ($img_str == "")) {
if ($quit_on_error && ($img_str == '')) {
return false;
}
$type = Images::getMimeTypeByData($img_str, $image_url, $type);
$Image = new Image($img_str, $type);
if ($Image->isValid()) {
$Image->scaleToSquare(300);
$image = new Image($img_str, $type);
if ($image->isValid()) {
$image->scaleToSquare(300);
$filesize = strlen($Image->asString());
$filesize = strlen($image->asString());
$maximagesize = DI::config()->get('system', 'maximagesize');
if (!empty($maximagesize) && ($filesize > $maximagesize)) {
Logger::info('Avatar exceeds image limit', ['uid' => $uid, 'cid' => $cid, 'maximagesize' => $maximagesize, 'size' => $filesize, 'type' => $Image->getType()]);
if ($Image->getType() == 'image/gif') {
$Image->toStatic();
$Image = new Image($Image->asString(), 'image/png');
Logger::info('Avatar exceeds image limit', ['uid' => $uid, 'cid' => $cid, 'maximagesize' => $maximagesize, 'size' => $filesize, 'type' => $image->getType()]);
if ($image->getType() == 'image/gif') {
$image->toStatic();
$image = new Image($image->asString(), 'image/png');
$filesize = strlen($Image->asString());
Logger::info('Converted gif to a static png', ['uid' => $uid, 'cid' => $cid, 'size' => $filesize, 'type' => $Image->getType()]);
$filesize = strlen($image->asString());
Logger::info('Converted gif to a static png', ['uid' => $uid, 'cid' => $cid, 'size' => $filesize, 'type' => $image->getType()]);
}
if ($filesize > $maximagesize) {
foreach ([160, 80] as $pixels) {
if ($filesize > $maximagesize) {
Logger::info('Resize', ['uid' => $uid, 'cid' => $cid, 'size' => $filesize, 'max' => $maximagesize, 'pixels' => $pixels, 'type' => $Image->getType()]);
$Image->scaleDown($pixels);
$filesize = strlen($Image->asString());
Logger::info('Resize', ['uid' => $uid, 'cid' => $cid, 'size' => $filesize, 'max' => $maximagesize, 'pixels' => $pixels, 'type' => $image->getType()]);
$image->scaleDown($pixels);
$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) {
$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) {
$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) {
$photo_failure = true;
}
$suffix = "?ts=" . time();
$suffix = '?ts=' . time();
$image_url = DI::baseUrl() . "/photo/" . $resource_id . "-4." . $Image->getExt() . $suffix;
$thumb = DI::baseUrl() . "/photo/" . $resource_id . "-5." . $Image->getExt() . $suffix;
$micro = DI::baseUrl() . "/photo/" . $resource_id . "-6." . $Image->getExt() . $suffix;
$image_url = DI::baseUrl() . '/photo/' . $resource_id . '-4.' . $image->getExt() . $suffix;
$thumb = DI::baseUrl() . '/photo/' . $resource_id . '-5.' . $image->getExt() . $suffix;
$micro = DI::baseUrl() . '/photo/' . $resource_id . '-6.' . $image->getExt() . $suffix;
} else {
$photo_failure = true;
}
@ -590,31 +590,33 @@ class Photo
* @param string $hemi hemi
* @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;
$minutes = count($exifCoord) > 1 ? self::gps2Num($exifCoord[1]) : 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)));
}
/**
* Change GPS to float number
*
* @param string $coordPart coordPart
* @return float
*/
private static function gps2Num($coordPart)
private static function gps2Num(string $coordPart): float
{
$parts = explode("/", $coordPart);
$parts = explode('/', $coordPart);
if (count($parts) <= 0) {
return 0;
}
if (count($parts) == 1) {
return $parts[0];
return (float)$parts[0];
}
return floatval($parts[0]) / floatval($parts[1]);
@ -631,17 +633,18 @@ class Photo
* @return array Returns array of the photo albums
* @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);
$avatar_type = (local_user() && (local_user() == $uid)) ? self::USER_AVATAR : 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);
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
// 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`
@ -674,19 +677,19 @@ class Photo
* @return void
* @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);
}
/**
* Generate a unique photo ID.
*
* @return string
* @return string Resource GUID
* @throws \Exception
*/
public static function newResource()
public static function newResource(): string
{
return System::createGUID(32, false);
}
@ -697,7 +700,7 @@ class 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
*/
public static function ridFromURI(string $image_uri)
public static function ridFromURI(string $image_uri): string
{
if (!stristr($image_uri, DI::baseUrl() . '/photo/')) {
return '';
@ -809,7 +812,7 @@ class Photo
* @param string $name Picture link
* @return array
*/
public static function getResourceData(string $name):array
public static function getResourceData(string $name): array
{
$base = DI::baseUrl()->get();
@ -840,8 +843,9 @@ class Photo
* @return boolean
* @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);
}
@ -851,7 +855,7 @@ class Photo
* @param string $name Picture link
* @return int
*/
public static function getIdForName($name)
public static function getIdForName(string $name): int
{
$data = self::getResourceData($name);
if (empty($data)) {
@ -872,7 +876,7 @@ class Photo
* @return boolean
* @throws \Exception
*/
public static function isLocalPage($name)
public static function isLocalPage(string $name): bool
{
$base = DI::baseUrl()->get();
@ -885,17 +889,23 @@ class Photo
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');
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]);
}
$filesize = strlen($Image->asString());
$width = $Image->getWidth();
$height = $Image->getHeight();
$filesize = strlen($image->asString());
$width = $image->getWidth();
$height = $image->getHeight();
$maximagesize = DI::config()->get('system', 'maximagesize');
@ -904,10 +914,10 @@ class Photo
foreach ([5120, 2560, 1280, 640] as $pixels) {
if (($filesize > $maximagesize) && (max($width, $height) > $pixels)) {
Logger::info('Resize', ['size' => $filesize, 'width' => $width, 'height' => $height, 'max' => $maximagesize, 'pixels' => $pixels]);
$Image->scaleDown($pixels);
$filesize = strlen($Image->asString());
$width = $Image->getWidth();
$height = $Image->getHeight();
$image->scaleDown($pixels);
$filesize = strlen($image->asString());
$width = $image->getWidth();
$height = $image->getHeight();
}
}
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);
if (!empty($image_url)) {
@ -939,17 +955,23 @@ class Photo
$type = Images::getMimeTypeByData($img_str, $image_url, $type);
$Image = new Image($img_str, $type);
$image = new Image($img_str, $type);
$Image = self::fitImageSize($Image);
if (empty($Image)) {
$image = self::fitImageSize($image);
if (empty($image)) {
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');
@ -1008,34 +1030,36 @@ class Photo
Logger::info('File upload', ['src' => $src, 'filename' => $filename, 'size' => $filesize, 'type' => $filetype]);
$imagedata = @file_get_contents($src);
$Image = new Image($imagedata, $filetype);
if (!$Image->isValid()) {
$image = new Image($imagedata, $filetype);
if (!$image->isValid()) {
Logger::notice('Image is unvalid', ['files' => $files]);
return [];
}
$Image->orient($src);
$image->orient($src);
@unlink($src);
$Image = self::fitImageSize($Image);
if (empty($Image)) {
$image = self::fitImageSize($image);
if (empty($image)) {
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 array $files uploaded file array
* @param string $album
* @param string $album Album name (optional)
* @param string|null $allow_cid
* @param string|null $allow_gid
* @param string $deny_cid
* @param string $deny_gid
* @param string $desc
* @param string $resource_id
* @return array photo record
* @param string $desc Description (optional)
* @param string $resource_id GUID (optional)
* @return array photo record or empty array on error
* @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
@ -1052,10 +1076,10 @@ class Photo
return [];
}
$Image = $data['image'];
$image = $data['image'];
$filename = $data['filename'];
$width = $Image->getWidth();
$height = $Image->getHeight();
$width = $image->getWidth();
$height = $image->getHeight();
$resource_id = $resource_id ?: self::newResource();
$album = $album ?: DI::l10n()->t('Wall Photos');
@ -1067,23 +1091,23 @@ class Photo
$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) {
Logger::notice('Photo could not be stored');
return [];
}
if ($width > 640 || $height > 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);
$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);
if ($r) {
$smallest = 1;
}
}
if ($width > 320 || $height > 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);
$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);
if ($r && ($smallest == 0)) {
$smallest = 2;
}
@ -1105,8 +1129,8 @@ class Photo
$picture['height'] = $photo['height'];
$picture['type'] = $photo['type'];
$picture['albumpage'] = DI::baseUrl() . '/photos/' . $user['nickname'] . '/image/' . $resource_id;
$picture['picture'] = DI::baseUrl() . '/photo/{$resource_id}-0.' . $Image->getExt();
$picture['preview'] = DI::baseUrl() . '/photo/{$resource_id}-{$smallest}.' . $Image->getExt();
$picture['picture'] = DI::baseUrl() . '/photo/{$resource_id}-0.' . $image->getExt();
$picture['preview'] = DI::baseUrl() . '/photo/{$resource_id}-{$smallest}.' . $image->getExt();
Logger::info('upload done', ['picture' => $picture]);
return $picture;
@ -1139,10 +1163,10 @@ class Photo
return '';
}
$Image = $data['image'];
$image = $data['image'];
$filename = $data['filename'];
$width = $Image->getWidth();
$height = $Image->getHeight();
$width = $image->getWidth();
$height = $image->getHeight();
$resource_id = self::newResource();
$album = DI::l10n()->t(self::PROFILE_PHOTOS);
@ -1151,28 +1175,28 @@ class Photo
logger::info('starting new profile image upload');
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) {
logger::notice('profile image upload with scale 4 (300) failed');
}
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) {
logger::notice('profile image upload with scale 5 (80) failed');
}
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) {
logger::notice('profile image upload with scale 6 (48) failed');
}
@ -1217,19 +1241,19 @@ class Photo
return '';
}
$Image = $data['image'];
$image = $data['image'];
$filename = $data['filename'];
$width = $Image->getWidth();
$height = $Image->getHeight();
$width = $image->getWidth();
$height = $image->getHeight();
$resource_id = self::newResource();
$album = DI::l10n()->t(self::BANNER_PHOTOS);
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) {
logger::notice('profile banner upload with scale 3 (960) failed');
}
@ -1247,3 +1271,4 @@ class Photo
return $resource_id;
}
}

View file

@ -39,7 +39,7 @@ class Post
* @return int ID of inserted post
* @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)) {
throw new BadMethodCallException('Empty URI_id');
@ -107,8 +107,10 @@ class Post
* @param object $stmt statement object
* @param bool $do_close
* @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)) {
return $stmt;
}
@ -131,7 +133,8 @@ class Post
* @return boolean Are there rows for that condition?
* @throws \Exception
*/
public static function exists($condition) {
public static function exists(array $condition): bool
{
return DBA::exists('post-user-view', $condition);
}
@ -151,7 +154,7 @@ class Post
* $count = Post::count($condition);
* @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);
}
@ -172,7 +175,7 @@ class Post
* $count = Post::count($condition);
* @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);
}
@ -193,7 +196,7 @@ class Post
* $count = Post::count($condition);
* @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);
}
@ -209,7 +212,7 @@ class Post
* @throws \Exception
* @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;
@ -234,7 +237,7 @@ class Post
* @throws \Exception
* @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;
@ -259,7 +262,7 @@ class Post
* @throws \Exception
* @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;
@ -284,7 +287,7 @@ class Post
* @return array
* @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);
@ -312,7 +315,7 @@ class Post
* @return boolean|object
* @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)) {
$selected = array_merge(Item::DISPLAY_FIELDLIST, Item::ITEM_FIELDLIST);
@ -337,7 +340,7 @@ class Post
* @return boolean|object
* @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);
}
@ -352,7 +355,7 @@ class Post
* @return boolean|object
* @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);
}
@ -367,7 +370,7 @@ class Post
* @return boolean|object
* @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);
}
@ -384,7 +387,7 @@ class Post
* @return boolean|object
* @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)) {
$selected = Item::DISPLAY_FIELDLIST;
@ -425,7 +428,7 @@ class Post
* @return boolean|object
* @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);
}
@ -441,7 +444,7 @@ class Post
* @return boolean|object
* @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);
}
@ -457,7 +460,7 @@ class Post
* @return boolean|object
* @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);
}
@ -473,7 +476,7 @@ class Post
* @throws \Exception
* @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;
@ -640,7 +643,7 @@ class Post
* @return boolean was the delete successful?
* @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);
}

View file

@ -40,36 +40,44 @@ class Link
/**
* Check if the link is stored
*
* @param int $uri_id
* @param string $url
* @return bool
* @param int $uriId
* @param string $url URL
* @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;
}
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;
}
$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'])) {
$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 {
$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();
Logger::info('Inserted', ['id' => $id, 'uri-id' => $uri_id, 'url' => $url]);
Logger::info('Inserted', ['id' => $id, 'uri-id' => $uriId, 'url' => $url]);
}
if (empty($id)) {
@ -81,15 +89,19 @@ class Link
case Proxy::SIZE_MICRO:
$url .= Proxy::PIXEL_MICRO . '/';
break;
case Proxy::SIZE_THUMB:
$url .= Proxy::PIXEL_THUMB . '/';
break;
case Proxy::SIZE_SMALL:
$url .= Proxy::PIXEL_SMALL . '/';
break;
case Proxy::SIZE_MEDIUM:
$url .= Proxy::PIXEL_MEDIUM . '/';
break;
case Proxy::SIZE_LARGE:
$url .= Proxy::PIXEL_LARGE . '/';
break;
@ -97,43 +109,50 @@ class Link
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');
$curlResult = DI::httpClient()->head($url, [HttpClientOptions::TIMEOUT => $timeout, HttpClientOptions::ACCEPT_CONTENT => $accept]);
if ($curlResult->isSuccess()) {
if (empty($media['mimetype'])) {
return $curlResult->getHeader('Content-Type')[0] ?? '';
}
if ($curlResult->isSuccess() && empty($media['mimetype'])) {
return $curlResult->getHeader('Content-Type')[0] ?? '';
}
return '';
}
/**
* Add external links and replace them in the body
*
* @param integer $uriid
* @param string $body
* @param integer $uriId
* @param string $body Item body formatted with BBCodes
* @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)) {
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)) {
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)) {
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
* @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'];
foreach ($fields as $field) {
@ -145,7 +145,7 @@ class Media
* @param string $title
* @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,
'size' => $length, 'mimetype' => $type, 'description' => $title]);
@ -160,7 +160,7 @@ class Media
* @param array $media
* @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'])) {
$media = self::fetchLocalData($media);
@ -192,7 +192,7 @@ class Media
if (($media['type'] == self::IMAGE) || ($filetype == 'image')) {
$imagedata = Images::getInfoFromURLCached($media['url']);
if (!empty($imagedata)) {
if ($imagedata) {
$media['mimetype'] = $imagedata['mime'];
$media['size'] = $imagedata['size'];
$media['width'] = $imagedata[0];
@ -202,7 +202,7 @@ class Media
}
if (!empty($media['preview'])) {
$imagedata = Images::getInfoFromURLCached($media['preview']);
if (!empty($imagedata)) {
if ($imagedata) {
$media['preview-width'] = $imagedata[0];
$media['preview-height'] = $imagedata[1];
}
@ -235,7 +235,7 @@ class Media
* @param array $media
* @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)) {
return $media;
@ -266,7 +266,7 @@ class Media
* @param array $data
* @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'])) {
Logger::info('No MimeType provided', ['media' => $data]);
@ -318,7 +318,7 @@ class Media
* @param string $preview Preview picture
* @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);
}
@ -330,7 +330,7 @@ class Media
* @param string $body
* @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
$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 string $body
* @return void
*/
public static function insertFromRelevantUrl(int $uriid, string $body)
{
@ -448,6 +449,7 @@ class Media
*
* @param integer $uriid
* @param string $body
* @return void
*/
public static function insertFromAttachmentData(int $uriid, string $body)
{
@ -506,9 +508,9 @@ class Media
/**
* Retrieves the media attachments associated with the provided item ID.
*
* @param int $uri_id
* @param array $types
* @return array
* @param int $uri_id URI id
* @param array $types Media types
* @return array|bool Array on success, false on error
* @throws \Exception
*/
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.
*
* @param int $uri_id
* @param array $types
* @return array
* @param int $uri_id URI id
* @param array $types Media types
* @return bool Whether media attachment exists
* @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];
@ -544,13 +546,13 @@ class Media
/**
* Split the attachment media in the three segments "visual", "link" and "additional"
*
* @param int $uri_id
* @param string $guid
* @param int $uri_id URI id
* @param string $guid GUID
* @param array $links list of links that shouldn't be added
* @param bool $has_media
* @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' => []];
@ -648,7 +650,7 @@ class Media
* @param 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)) {
$item = Post::selectFirst(['body'], ['uri-id' => $uriid]);
@ -701,7 +703,7 @@ class Media
* @param string $size One of the Proxy::SIZE_* constants
* @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/';
switch ($size) {
@ -731,7 +733,7 @@ class Media
* @param string $size One of the Proxy::SIZE_* constants
* @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/';
switch ($size) {

View file

@ -54,10 +54,10 @@ class Profile
*
* @param integer User ID
*
* @return array Profile data
* @return array|bool Profile data or false on error
* @throws \Exception
*/
public static function getByUID($uid)
public static function getByUID(int $uid)
{
return DBA::selectFirst('profile', [], ['uid' => $uid]);
}
@ -69,7 +69,7 @@ class Profile
* @param int $id The contact owner ID
* @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
*/
public static function getById(int $uid, int $id, array $fields = [])
@ -81,7 +81,7 @@ class Profile
* Returns profile data for the contact owner
*
* @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
* @throws \Exception
@ -94,9 +94,9 @@ class Profile
/**
* Update a profile entry and distribute the changes if needed
*
* @param array $fields
* @param integer $uid
* @return boolean
* @param array $fields Profile fields to update
* @param integer $uid User id
* @return boolean Whether update was successful
*/
public static function update(array $fields, int $uid): bool
{
@ -136,8 +136,10 @@ class Profile
/**
* Publish a changed profile
* @param int $uid
*
* @param int $uid User id
* @param bool $force Force publishing to the directory
* @return void
*/
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
*
* @param array $profile Profile array (Generated from the "profile" table)
*
* @return string Location string
*/
public static function formatLocation(array $profile)
public static function formatLocation(array $profile): string
{
$location = '';
@ -237,7 +238,7 @@ class Profile
if (!local_user()) {
$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 int $default_priority
* @return void
* @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];
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
*
* @param int $default_priority
* @return void
* @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,
// 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_topic Feed topic
* @param string $hub_secret Subscription secret
* @return void
* @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
$subscriber = DBA::selectFirst('push_subscriber', ['last_update', 'push'], ['callback_url' => $hub_callback]);
@ -119,9 +122,10 @@ class PushSubscriber
* Delay the push subscriber
*
* @param integer $id Subscriber ID
* @return void
* @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]);
if (!DBA::isResult($subscriber)) {
@ -158,9 +162,10 @@ class PushSubscriber
*
* @param integer $id Subscriber ID
* @param string $last_update Date of last transmitted item
* @return void
* @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]);
if (!DBA::isResult($subscriber)) {

View file

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

View file

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

View file

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

View file

@ -73,13 +73,14 @@ class Tag
/**
* Store tag/mention elements
*
* @param integer $uriid
* @param integer $type
* @param string $name
* @param string $url
* @param integer $target
* @param integer $uriId
* @param integer $type Tag type
* @param string $name Tag name
* @param string $url Contact URL (optional)
* @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) {
// Trim Unicode non-word characters
@ -88,7 +89,7 @@ class Tag
$tags = explode(self::TAG_CHARACTER[self::HASHTAG], $name);
if (count($tags) > 1) {
foreach ($tags as $tag) {
self::store($uriid, $type, $tag, $url);
self::store($uriId, $type, $tag, $url);
}
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])) {
$condition = $fields;
@ -155,7 +156,7 @@ class Tag
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 int $type
* @return void
* @param int $type Type of tag
* @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];
@ -242,6 +243,9 @@ class Tag
return $tid;
}
// Also log type
$fields['type'] = $type;
Logger::error('No tag id created', $fields);
return 0;
}
@ -249,20 +253,21 @@ class Tag
/**
* Store tag/mention elements
*
* @param integer $uriid
* @param integer $uriId
* @param string $hash
* @param string $name
* @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);
if ($type == self::UNKNOWN) {
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
*/
public static function getFromBody(string $body, string $tags = null)
public static function getFromBody(string $body, string $tags = null): array
{
if (is_null($tags)) {
$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
*
* @param integer $uriid URI-Id
* @param integer $uriId URI-Id
* @param string $body Body of the post
* @param string $tags Accepted tags
* @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)) {
$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) {
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)
if (!empty($share_body) && (strpos($tags, self::TAG_CHARACTER[self::HASHTAG]) !== false)) {
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.
* 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
* @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);
if (empty($result)) {
return;
}
Logger::info('Found tags', ['uri-id' => $uriid, 'result' => $result]);
Logger::info('Found tags', ['uri-id' => $uriId, 'result' => $result]);
foreach ($result as $tag) {
if (substr($tag, 0, 1) != self::TAG_CHARACTER[self::HASHTAG]) {
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
*
* @param integer $uriid
* @param integer $uriId
* @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
*
* @param integer $uriid
* @param integer $type
* @param string $name
* @param string $url
* @param integer $uriId
* @param integer $type Type
* @param string $name Name
* @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) {
$condition['name'] = $name;
}
@ -381,35 +389,36 @@ class Tag
return;
}
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']]);
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']]);
}
/**
* Remove tag/mention
*
* @param integer $uriid
* @param integer $uriId
* @param string $hash
* @param string $name
* @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);
if ($type == self::UNKNOWN) {
return;
}
self::remove($uriid, $type, $name, $url);
self::remove($uriId, $type, $name, $url);
}
/**
* Get the type for the given 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]) {
return self::MENTION;
@ -427,22 +436,23 @@ class Tag
/**
* Create implicit mentions for a given post
*
* @param integer $uri_id
* @param integer $parent_uri_id
* @param integer $uriId
* @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
$parent = Post::selectFirst(['author-link', 'author-name'], ['uri-id' => $parent_uri_id]);
self::store($uri_id, self::IMPLICIT_MENTION, $parent['author-name'], $parent['author-link']);
$parent = Post::selectFirst(['author-link', 'author-name'], ['uri-id' => $parentUriId]);
self::store($uriId, self::IMPLICIT_MENTION, $parent['author-name'], $parent['author-link']);
if (DI::config()->get('system', 'disable_implicit_mentions')) {
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)) {
self::store($uri_id, self::IMPLICIT_MENTION, $tag['name'], $tag['url']);
self::store($uriId, self::IMPLICIT_MENTION, $tag['name'], $tag['url']);
}
DBA::close($tags);
}
@ -450,30 +460,29 @@ class Tag
/**
* Retrieves the terms from the provided type(s) associated with the provided item ID.
*
* @param int $item_id
* @param int|array $type
* @return array
* @param int $uriId
* @param array $type Tag type(s)
* @return array|bool Array on success, false on error
* @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 a string with all tags and mentions
*
* @param integer $uri_id
* @param array $type
* @param integer $uriId
* @param array $type Tag type(s)
* @return string tags and mentions
* @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 = [];
$tags = self::getByURIId($uri_id, $type);
foreach ($tags as $tag) {
foreach (self::getByURIId($uriId, $type) as $tag) {
$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 \ImagickException
*/
public static function populateFromItem(&$item)
public static function populateFromItem(array &$item): array
{
$return = [
'tags' => [],
@ -498,7 +507,7 @@ class Tag
'implicit_mentions' => [],
];
$searchpath = DI::baseUrl() . "/search?tag=";
$searchpath = DI::baseUrl() . '/search?tag=';
$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]]);
@ -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['tags'][] = '<bdi>' . $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['name']) . '</a></bdi>';
break;
case self::MENTION:
case self::EXCLUSIVE_MENTION:
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['tags'][] = '<bdi>' . $prefix . '<a href="' . $tag['url'] . '" target="_blank" rel="noopener noreferrer">' . htmlspecialchars($tag['name']) . '</a></bdi>';
break;
case self::IMPLICIT_MENTION:
$return['implicit_mentions'][] = $prefix . $tag['name'];
break;
default:
Logger:warning('Unknown tag type found', $tag);
}
}
DBA::close($taglist);
@ -546,11 +560,13 @@ class Tag
* @param integer $uid
* @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`))
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);
}
@ -558,18 +574,20 @@ class Tag
/**
* Search posts for given tag
*
* @param string $search
* @param integer $uid
* @param integer $start
* @param integer $limit
* @param string $search Tag to search for
* @param integer $uid User Id
* @param integer $start Starting record
* @param integer $limit Maximum count of records
* @param integer $last_uriid
* @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`))
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)) {
$condition = DBA::mergeConditions($condition, ["`uri-id` < ?", $last_uriid]);
@ -582,13 +600,13 @@ class Tag
$tags = DBA::select('tag-search-view', ['uri-id'], $condition, $params);
$uriids = [];
$uriIds = [];
while ($tag = DBA::fetch($tags)) {
$uriids[] = $tag['uri-id'];
$uriIds[] = $tag['uri-id'];
}
DBA::close($tags);
return $uriids;
return $uriIds;
}
/**
@ -599,7 +617,7 @@ class Tag
* @return array
* @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);
if (!empty($tags)) {
@ -612,9 +630,9 @@ class Tag
/**
* 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');
if (empty($blocked_txt)) {
@ -623,7 +641,7 @@ class Tag
$blocked = explode(',', $blocked_txt);
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
* @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')],
['order' => ['received' => true]]);
if (empty($post['uri-id'])) {
return [];
}
@ -650,7 +671,9 @@ class Tag
FROM `tag-search-view`
WHERE `private` = ? AND `uid` = ? AND `uri-id` > ? $block_sql
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)) {
$tags = DBA::toArray($tagsStmt);
@ -669,7 +692,7 @@ class Tag
* @return array
* @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);
if (!empty($tags)) {
@ -687,7 +710,7 @@ class Tag
* @return array
* @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.
// 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`
WHERE `private` = ? AND `wall` AND `origin` AND `uri-id` > ? $block_sql
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)) {
$tags = DBA::toArray($tagsStmt);
@ -717,11 +742,11 @@ class Tag
/**
* Check if the provided tag is of one of the provided term types.
*
* @param string $tag
* @param string $tag Tag name
* @param int ...$types
* @return bool
*/
public static function isType($tag, ...$types)
public static function isType(string $tag, ...$types): bool
{
$tag_chars = [];
foreach ($types as $type) {
@ -739,7 +764,7 @@ class Tag
* @param string $tag
* @return array User list
*/
private static function getUIDListByTag(string $tag)
private static function getUIDListByTag(string $tag): array
{
$uids = [];
$searches = DBA::select('search', ['uid'], ['term' => $tag]);
@ -754,13 +779,13 @@ class Tag
/**
* Fetch user who subscribed to the tags of the given item
*
* @param integer $uri_id
* @param integer $uriId
* @return array User list
*/
public static function getUIDListByURIId(int $uri_id)
public static function getUIDListByURIId(int $uriId): array
{
$uids = [];
$tags = self::getByURIId($uri_id, [self::HASHTAG]);
$tags = self::getByURIId($uriId, [self::HASHTAG]);
foreach ($tags as $tag) {
$uids = array_merge($uids, self::getUIDListByTag(self::TAG_CHARACTER[self::HASHTAG] . $tag['name']));

View file

@ -117,16 +117,18 @@ class User
switch ($accounttype) {
case 'person':
return User::ACCOUNT_TYPE_PERSON;
case 'organisation':
return User::ACCOUNT_TYPE_ORGANISATION;
case 'news':
return User::ACCOUNT_TYPE_NEWS;
case 'community':
return User::ACCOUNT_TYPE_COMMUNITY;
default:
return null;
break;
}
return null;
}
/**
@ -134,7 +136,7 @@ class User
*
* @return array system account
*/
public static function getSystemAccount()
public static function getSystemAccount(): array
{
$system = Contact::selectFirst([], ['self' => true, 'uid' => 0]);
if (!DBA::isResult($system)) {
@ -244,7 +246,7 @@ class User
*
* @return string actor account name
*/
public static function getActorName()
public static function getActorName(): string
{
$system_actor_name = DI::config()->get('system', 'actor_name');
if (!empty($system_actor_name)) {
@ -278,7 +280,7 @@ class User
* @return boolean
* @throws Exception
*/
public static function exists($uid)
public static function exists(int $uid): bool
{
return DBA::exists('user', ['uid' => $uid]);
}
@ -289,7 +291,7 @@ class User
* @return array|boolean User record if it exists, false otherwise
* @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]) : [];
}
@ -321,7 +323,7 @@ class User
* @return array|boolean User record if it exists, false otherwise
* @throws Exception
*/
public static function getByNickname($nickname, array $fields = [])
public static function getByNickname(string $nickname, array $fields = [])
{
return DBA::selectFirst('user', $fields, ['nickname' => $nickname]);
}
@ -334,7 +336,7 @@ class User
* @return integer user id
* @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.
if (!Contact::isLocal($url)) {
@ -362,14 +364,12 @@ class User
/**
* Get a user based on its email
*
* @param string $email
* @param array $fields
*
* @param string $email
* @param array $fields
* @return array|boolean User record if it exists, false otherwise
*
* @throws Exception
*/
public static function getByEmail($email, array $fields = [])
public static function getByEmail(string $email, array $fields = [])
{
return DBA::selectFirst('user', $fields, ['email' => $email]);
}
@ -380,7 +380,7 @@ class User
* @param array $fields
* @return array user
*/
public static function getFirstAdmin(array $fields = [])
public static function getFirstAdmin(array $fields = []) : array
{
if (!empty(DI::config()->get('config', 'admin_nickname'))) {
return self::getByNickname(DI::config()->get('config', 'admin_nickname'), $fields);
@ -469,7 +469,7 @@ class User
* @return boolean|array
* @throws Exception
*/
public static function getOwnerDataByNick($nick)
public static function getOwnerDataByNick(string $nick)
{
$user = DBA::selectFirst('user', ['uid'], ['nickname' => $nick]);
@ -488,7 +488,7 @@ class User
* @return int group id
* @throws Exception
*/
public static function getDefaultGroup($uid)
public static function getDefaultGroup(int $uid): int
{
$user = DBA::selectFirst('user', ['def_gid'], ['uid' => $uid]);
if (DBA::isResult($user)) {
@ -512,7 +512,7 @@ class User
* @throws HTTPException\ForbiddenException
* @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
// 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
* @throws HTTPException\ForbiddenException
*/
public static function getIdFromAuthenticateHooks($username, $password)
public static function getIdFromAuthenticateHooks(string $username, string $password): int
{
$addon_auth = [
'username' => $username,
@ -613,7 +613,7 @@ class User
* - User array with at least the uid and the hashed password
*
* @param mixed $user_info
* @return array
* @return array|null Null if not found/determined
* @throws HTTPException\NotFoundException
*/
public static function getAuthenticationInfo($user_info)
@ -671,7 +671,7 @@ class User
* @return string
* @throws Exception
*/
public static function generateNewPassword()
public static function generateNewPassword(): string
{
return ucfirst(Strings::getRandomName(8)) . random_int(1000, 9999);
}
@ -683,7 +683,7 @@ class User
* @return bool
* @throws Exception
*/
public static function isPasswordExposed($password)
public static function isPasswordExposed(string $password): bool
{
$cache = new CacheItemPool();
$cache->changeConfig([
@ -712,7 +712,7 @@ class User
* @param string $password
* @return string
*/
private static function hashPasswordLegacy($password)
private static function hashPasswordLegacy(string $password): string
{
return hash('whirlpool', $password);
}
@ -724,7 +724,7 @@ class User
* @return string
* @throws Exception
*/
public static function hashPassword($password)
public static function hashPassword(string $password): string
{
if (!trim($password)) {
throw new Exception(DI::l10n()->t('Password can\'t be empty'));
@ -741,7 +741,7 @@ class User
* @return bool
* @throws Exception
*/
public static function updatePassword($uid, $password)
public static function updatePassword(int $uid, string $password): bool
{
$password = trim($password);
@ -771,7 +771,7 @@ class User
* @return bool
* @throws Exception
*/
private static function updatePasswordHashed($uid, $pasword_hashed)
private static function updatePasswordHashed(int $uid, string $pasword_hashed): bool
{
$fields = [
'password' => $pasword_hashed,
@ -792,7 +792,7 @@ class User
* @param string $nickname The nickname that should be checked
* @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', '');
if (!empty($forbidden_nicknames)) {
@ -829,7 +829,7 @@ class User
* @return string avatar link
* @throws Exception
*/
public static function getAvatarUrl(array $user, string $size = ''):string
public static function getAvatarUrl(array $user, string $size = ''): string
{
if (empty($user['nickname'])) {
DI::logger()->warning('Missing user nickname key', ['trace' => System::callstack(20)]);
@ -871,7 +871,7 @@ class User
* @return string banner link
* @throws Exception
*/
public static function getBannerUrl(array $user):string
public static function getBannerUrl(array $user): string
{
if (empty($user['nickname'])) {
DI::logger()->warning('Missing user nickname key', ['trace' => System::callstack(20)]);
@ -913,7 +913,7 @@ class User
* @throws ImagickException
* @throws Exception
*/
public static function create(array $data)
public static function create(array $data): array
{
$return = ['user' => null, 'password' => ''];
@ -1164,32 +1164,32 @@ class User
$type = Images::getMimeTypeByData($img_str, $photo, $type);
$Image = new Image($img_str, $type);
if ($Image->isValid()) {
$Image->scaleToSquare(300);
$image = new Image($img_str, $type);
if ($image->isValid()) {
$image->scaleToSquare(300);
$resource_id = Photo::newResource();
// Not using Photo::PROFILE_PHOTOS here, so that it is discovered as translateble string
$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) {
$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) {
$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) {
$photo_failure = true;
@ -1255,7 +1255,7 @@ class User
* @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]);
}
@ -1270,7 +1270,7 @@ class User
* @throws HTTPException\InternalServerErrorException
* @throws Exception
*/
public static function allow(string $hash)
public static function allow(string $hash): bool
{
$register = Register::getByHash($hash);
if (!DBA::isResult($register)) {
@ -1316,7 +1316,7 @@ class User
* @return bool True, if the deny was successfull
* @throws Exception
*/
public static function deny(string $hash)
public static function deny(string $hash): bool
{
$register = Register::getByHash($hash);
if (!DBA::isResult($register)) {
@ -1342,13 +1342,12 @@ class User
* @param string $email The user's email address
* @param string $nick The user's nick name
* @param string $lang The user's language (default is english)
*
* @return bool True, if the user was created successfully
* @throws HTTPException\InternalServerErrorException
* @throws ErrorException
* @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) ||
empty($email) ||
@ -1418,7 +1417,7 @@ class User
* @return NULL|boolean from notification() and email() inherited
* @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(
'
@ -1461,7 +1460,7 @@ class User
* @return NULL|boolean from notification() and email() inherited
* @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(
'
@ -1520,7 +1519,7 @@ class User
* @return bool
* @throws HTTPException\InternalServerErrorException
*/
public static function remove(int $uid)
public static function remove(int $uid): bool
{
if (empty($uid)) {
return false;
@ -1574,7 +1573,7 @@ class User
* ]
* @throws Exception
*/
public static function identities($uid)
public static function identities(int $uid): array
{
if (empty($uid)) {
return [];
@ -1646,7 +1645,7 @@ class User
* @param int $uid
* @return bool
*/
public static function hasIdentities(int $uid):bool
public static function hasIdentities(int $uid): bool
{
if (empty($uid)) {
return false;
@ -1679,7 +1678,7 @@ class User
*
* @throws Exception
*/
public static function getStatistics()
public static function getStatistics(): array
{
$statistics = [
'total_users' => 0,
@ -1731,11 +1730,10 @@ class User
* @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 bool $descending Order direction (Default is ascending)
*
* @return array The list of the users
* @return array|bool The list of the users
* @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]];
$condition = [];
@ -1744,11 +1742,13 @@ class User
$condition['account_removed'] = false;
$condition['blocked'] = false;
break;
case 'blocked':
$condition['account_removed'] = false;
$condition['blocked'] = true;
$condition['verified'] = true;
break;
case 'removed':
$condition['account_removed'] = true;
break;

View file

@ -52,12 +52,12 @@ class Cookie
private $data;
/**
* @param App\Request $request The current http request
* @param IManageConfigValues $config
* @param App\BaseURL $baseURL
* @param array $SERVER The $_SERVER 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->sitePrivateKey = $config->get('system', 'site_prvkey');
@ -66,7 +66,7 @@ class Cookie
self::DEFAULT_EXPIRE);
$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) ?: [];
}

View file

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

View file

@ -54,12 +54,12 @@ class Summary extends BaseAdmin
$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');
}
// 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');
}

View file

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

View file

@ -48,7 +48,7 @@ class BaseSettings extends BaseModule
'label' => DI::l10n()->t('Two-factor authentication'),
'url' => 'settings/2fa',
'selected' => ((DI::args()->getArgc() > 1) && (DI::args()->getArgv()[1] === '2fa') ? 'active' : ''),
'accesskey' => 'o',
'accesskey' => '2',
];
$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);
if (!$msg) {
if (!is_array($msg)) {
// 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
@ -88,10 +89,10 @@ class Notify extends BaseModule
System::xmlExit($ret, 'Done');
}
private static function dispatchPrivate($user, $postdata)
private static function dispatchPrivate(array $user, string $postdata)
{
$msg = Diaspora::decodeRaw($postdata, $user['prvkey'] ?? '');
if (!$msg) {
if (!is_array($msg)) {
System::xmlExit(4, 'Unable to parse message');
}

View file

@ -34,6 +34,6 @@ class Poll extends BaseModule
protected function rawContent(array $request = [])
{
$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