diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 24f36436d5..10fbd69589 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -25,12 +25,9 @@ jobs: - '8.1' - '8.0' - '7.4' - - '7.3' - - '7.2' include: - php: '7.4' phpstan: true - - php: '7.2' cs_fixer: true check_client: true - php: '8.2' diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 7a953abf76..dcdbb51691 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -10,9 +10,14 @@ '@Symfony' => true, // why would anyone put braces on different line 'braces' => ['position_after_functions_and_oop_constructs' => 'same'], - 'function_declaration' => ['closure_function_spacing' => 'none'], + 'function_declaration' => [ + 'closure_function_spacing' => 'none', + 'closure_fn_spacing' => 'none', + ], // overwrite some Symfony rules 'concat_space' => ['spacing' => 'one'], + 'global_namespace_import' => false, + 'blank_line_between_import_groups' => false, 'phpdoc_align' => false, 'phpdoc_no_empty_return' => false, 'phpdoc_summary' => false, diff --git a/NEWS.md b/NEWS.md index fe45909eba..e5928f3291 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,7 +1,7 @@ # selfoss news ## 2.20 – unreleased -**This version currently requires PHP 7.2.5 or newer. (Will be increased later.)** +**This version currently requires PHP 7.4 or newer. (Might be increased later.)** ### New features - YouTube spout now accepts handles (starting with `@` sign). ([#1412](https://github.com/fossar/selfoss/pull/1412)) @@ -24,6 +24,7 @@ - Custom spout parameter declarations should now use constants from `Parameter` interface. ([#1409](https://github.com/fossar/selfoss/pull/1409)) - Custom spouts are expected to pass `HtmlString` object to items’ title and content. ([#1368](https://github.com/fossar/selfoss/pull/1368)) - Spouts can fetch item contents lazily by passing a function as `content` to `Item`. ([#1413](https://github.com/fossar/selfoss/pull/1413)) +- Spouts’ `name`, `description` and `params` properties now require a type hint. ([#1425](https://github.com/fossar/selfoss/pull/1425)) ### Other changes - `tidy` PHP extension is now required if you want to use “Content extractor” spout. ([#1392](https://github.com/fossar/selfoss/pull/1392)) diff --git a/composer.json b/composer.json index 2d4b0b3b1e..479a7942a9 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "Multipurpose rss reader, live stream, mashup, aggregation web application", "type": "project", "require": { - "php": ">= 7.2.5", + "php": ">= 7.4.0", "ext-gd": "*", "bcosca/fatfree-core": "^3.8", "bramus/router": "^1.6", @@ -52,7 +52,7 @@ }, "config": { "platform": { - "php": "7.2.5" + "php": "7.4.0" }, "allow-plugins": false, "sort-packages": true diff --git a/composer.lock b/composer.lock index 6d289e758b..b02e14a2f8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f2260c85ad19e64591150833ce86bfa7", + "content-hash": "3d8473e8857fadb3e40111ac659d7270", "packages": [ { "name": "bcosca/fatfree-core", @@ -720,20 +720,21 @@ }, { "name": "http-interop/http-factory-guzzle", - "version": "1.1.1", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/http-interop/http-factory-guzzle.git", - "reference": "6e1efa1e020bf1c47cf0f13654e8ef9efb1463b3" + "reference": "8f06e92b95405216b237521cc64c804dd44c4a81" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/http-interop/http-factory-guzzle/zipball/6e1efa1e020bf1c47cf0f13654e8ef9efb1463b3", - "reference": "6e1efa1e020bf1c47cf0f13654e8ef9efb1463b3", + "url": "https://api.github.com/repos/http-interop/http-factory-guzzle/zipball/8f06e92b95405216b237521cc64c804dd44c4a81", + "reference": "8f06e92b95405216b237521cc64c804dd44c4a81", "shasum": "" }, "require": { - "guzzlehttp/psr7": "^1.4.2||^2.0", + "guzzlehttp/psr7": "^1.7||^2.0", + "php": ">=7.3", "psr/http-factory": "^1.0" }, "provide": { @@ -741,7 +742,10 @@ }, "require-dev": { "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5" + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "guzzlehttp/psr7": "Includes an HTTP factory starting in version 2.0" }, "type": "library", "autoload": { @@ -768,9 +772,9 @@ ], "support": { "issues": "https://github.com/http-interop/http-factory-guzzle/issues", - "source": "https://github.com/http-interop/http-factory-guzzle/tree/1.1.1" + "source": "https://github.com/http-interop/http-factory-guzzle/tree/1.2.0" }, - "time": "2021-07-23T15:14:50+00:00" + "time": "2021-07-21T13:50:14+00:00" }, { "name": "http-interop/response-sender", @@ -948,20 +952,20 @@ }, { "name": "j0k3r/httplug-ssrf-plugin", - "version": "v2.0.1", + "version": "v2.0.2", "source": { "type": "git", "url": "https://github.com/j0k3r/httplug-ssrf-plugin.git", - "reference": "fb68804e3bace2b894d1b9f39ad2b59078f5eac2" + "reference": "b60e8068054bdb15fdf1e62cd314d941c62a3b72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/j0k3r/httplug-ssrf-plugin/zipball/fb68804e3bace2b894d1b9f39ad2b59078f5eac2", - "reference": "fb68804e3bace2b894d1b9f39ad2b59078f5eac2", + "url": "https://api.github.com/repos/j0k3r/httplug-ssrf-plugin/zipball/b60e8068054bdb15fdf1e62cd314d941c62a3b72", + "reference": "b60e8068054bdb15fdf1e62cd314d941c62a3b72", "shasum": "" }, "require": { - "php": "^7.1", + "php": ">=7.2.9", "php-http/client-common": "^2.0", "php-http/discovery": "^1.5", "php-http/message": "^1.7", @@ -972,9 +976,10 @@ "guzzlehttp/psr7": "^1.0", "php-http/guzzle6-adapter": "^2.0", "php-http/mock-client": "^1.0", - "phpstan/phpstan": "^0.11", - "phpstan/phpstan-phpunit": "^0.11", - "symfony/phpunit-bridge": "~3.4.19|~4.0" + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "symfony/phpunit-bridge": "~5.0" }, "type": "library", "autoload": { @@ -1014,7 +1019,7 @@ "issues": "https://github.com/j0k3r/httplug-ssrf-plugin/issues", "source": "https://github.com/j0k3r/httplug-ssrf-plugin/tree/master" }, - "time": "2020-01-06T13:44:13+00:00" + "time": "2020-06-26T06:05:06+00:00" }, { "name": "j0k3r/php-readability", @@ -1552,16 +1557,16 @@ }, { "name": "php-http/discovery", - "version": "1.15.2", + "version": "1.15.3", "source": { "type": "git", "url": "https://github.com/php-http/discovery.git", - "reference": "5cc428320191ac1d0b6520034c2dc0698628ced5" + "reference": "3ccd28dd9fb34b52db946abea1b538568e34eae8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/discovery/zipball/5cc428320191ac1d0b6520034c2dc0698628ced5", - "reference": "5cc428320191ac1d0b6520034c2dc0698628ced5", + "url": "https://api.github.com/repos/php-http/discovery/zipball/3ccd28dd9fb34b52db946abea1b538568e34eae8", + "reference": "3ccd28dd9fb34b52db946abea1b538568e34eae8", "shasum": "" }, "require": { @@ -1620,9 +1625,9 @@ ], "support": { "issues": "https://github.com/php-http/discovery/issues", - "source": "https://github.com/php-http/discovery/tree/1.15.2" + "source": "https://github.com/php-http/discovery/tree/1.15.3" }, - "time": "2023-02-11T08:28:41+00:00" + "time": "2023-03-31T14:40:37+00:00" }, { "name": "php-http/guzzle7-adapter", @@ -1984,20 +1989,20 @@ }, { "name": "psr/container", - "version": "1.1.1", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", + "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", "shasum": "" }, "require": { - "php": ">=7.2.0" + "php": ">=7.4.0" }, "type": "library", "autoload": { @@ -2026,9 +2031,9 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.1" + "source": "https://github.com/php-fig/container/tree/1.1.2" }, - "time": "2021-03-05T17:36:06+00:00" + "time": "2021-11-05T16:50:12+00:00" }, { "name": "psr/http-client", @@ -2502,16 +2507,16 @@ }, { "name": "symfony/cache", - "version": "v5.4.21", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "32cab695bf99c63aff7d27ac67919944c00530ed" + "reference": "5ed986c4ef65f0dea5e9753630b5cb1f07f847d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/32cab695bf99c63aff7d27ac67919944c00530ed", - "reference": "32cab695bf99c63aff7d27ac67919944c00530ed", + "url": "https://api.github.com/repos/symfony/cache/zipball/5ed986c4ef65f0dea5e9753630b5cb1f07f847d6", + "reference": "5ed986c4ef65f0dea5e9753630b5cb1f07f847d6", "shasum": "" }, "require": { @@ -2579,7 +2584,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v5.4.21" + "source": "https://github.com/symfony/cache/tree/v5.4.22" }, "funding": [ { @@ -2595,7 +2600,7 @@ "type": "tidelift" } ], - "time": "2023-02-21T12:11:13+00:00" + "time": "2023-03-29T20:01:08+00:00" }, { "name": "symfony/cache-contracts", @@ -3568,30 +3573,30 @@ "packages-dev": [ { "name": "composer/pcre", - "version": "1.0.1", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560" + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/67a32d7d6f9f560b726ab25a061b38ff3a80c560", - "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560", + "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" + "php": "^7.4 || ^8.0" }, "require-dev": { "phpstan/phpstan": "^1.3", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^4.2 || ^5" + "symfony/phpunit-bridge": "^5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.x-dev" + "dev-main": "3.x-dev" } }, "autoload": { @@ -3619,7 +3624,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/1.0.1" + "source": "https://github.com/composer/pcre/tree/3.1.0" }, "funding": [ { @@ -3635,7 +3640,7 @@ "type": "tidelift" } ], - "time": "2022-01-21T20:24:37+00:00" + "time": "2022-11-17T09:50:14+00:00" }, { "name": "composer/semver", @@ -3720,27 +3725,27 @@ }, { "name": "composer/xdebug-handler", - "version": "2.0.5", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "9e36aeed4616366d2b690bdce11f71e9178c579a" + "reference": "ced299686f41dce890debac69273b47ffe98a40c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/9e36aeed4616366d2b690bdce11f71e9178c579a", - "reference": "9e36aeed4616366d2b690bdce11f71e9178c579a", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", + "reference": "ced299686f41dce890debac69273b47ffe98a40c", "shasum": "" }, "require": { - "composer/pcre": "^1", - "php": "^5.3.2 || ^7.0 || ^8.0", + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", "psr/log": "^1 || ^2 || ^3" }, "require-dev": { "phpstan/phpstan": "^1.0", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0" + "symfony/phpunit-bridge": "^6.0" }, "type": "library", "autoload": { @@ -3766,7 +3771,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/2.0.5" + "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" }, "funding": [ { @@ -3782,34 +3787,34 @@ "type": "tidelift" } ], - "time": "2022-02-24T20:20:32+00:00" + "time": "2022-02-25T21:32:43+00:00" }, { "name": "doctrine/annotations", - "version": "1.14.3", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af" + "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af", - "reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", + "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", "shasum": "" }, "require": { - "doctrine/lexer": "^1 || ^2", + "doctrine/lexer": "^2 || ^3", "ext-tokenizer": "*", - "php": "^7.1 || ^8.0", + "php": "^7.2 || ^8.0", "psr/cache": "^1 || ^2 || ^3" }, "require-dev": { - "doctrine/cache": "^1.11 || ^2.0", - "doctrine/coding-standard": "^9 || ^10", - "phpstan/phpstan": "~1.4.10 || ^1.8.0", + "doctrine/cache": "^2.0", + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.8.0", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "symfony/cache": "^4.4 || ^5.4 || ^6", + "symfony/cache": "^5.4 || ^6", "vimeo/psalm": "^4.10" }, "suggest": { @@ -3856,9 +3861,9 @@ ], "support": { "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.14.3" + "source": "https://github.com/doctrine/annotations/tree/2.0.1" }, - "time": "2023-02-01T09:20:38+00:00" + "time": "2023-02-02T22:02:53+00:00" }, { "name": "doctrine/deprecations", @@ -3983,52 +3988,53 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.4.0", + "version": "v3.15.1", "source": { "type": "git", - "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "47177af1cfb9dab5d1cc4daf91b7179c2efe7fad" + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "d48755372a113bddb99f749e34805d83f3acfe04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/47177af1cfb9dab5d1cc4daf91b7179c2efe7fad", - "reference": "47177af1cfb9dab5d1cc4daf91b7179c2efe7fad", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/d48755372a113bddb99f749e34805d83f3acfe04", + "reference": "d48755372a113bddb99f749e34805d83f3acfe04", "shasum": "" }, "require": { - "composer/semver": "^3.2", - "composer/xdebug-handler": "^2.0", - "doctrine/annotations": "^1.12", + "composer/semver": "^3.3", + "composer/xdebug-handler": "^3.0.3", + "doctrine/annotations": "^2", + "doctrine/lexer": "^2 || ^3", "ext-json": "*", "ext-tokenizer": "*", - "php": "^7.2.5 || ^8.0", - "php-cs-fixer/diff": "^2.0", - "symfony/console": "^4.4.20 || ^5.1.3 || ^6.0", - "symfony/event-dispatcher": "^4.4.20 || ^5.0 || ^6.0", - "symfony/filesystem": "^4.4.20 || ^5.0 || ^6.0", - "symfony/finder": "^4.4.20 || ^5.0 || ^6.0", - "symfony/options-resolver": "^4.4.20 || ^5.0 || ^6.0", - "symfony/polyfill-mbstring": "^1.23", - "symfony/polyfill-php80": "^1.23", - "symfony/polyfill-php81": "^1.23", - "symfony/process": "^4.4.20 || ^5.0 || ^6.0", - "symfony/stopwatch": "^4.4.20 || ^5.0 || ^6.0" + "php": "^7.4 || ^8.0", + "sebastian/diff": "^4.0 || ^5.0", + "symfony/console": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/filesystem": "^5.4 || ^6.0", + "symfony/finder": "^5.4 || ^6.0", + "symfony/options-resolver": "^5.4 || ^6.0", + "symfony/polyfill-mbstring": "^1.27", + "symfony/polyfill-php80": "^1.27", + "symfony/polyfill-php81": "^1.27", + "symfony/process": "^5.4 || ^6.0", + "symfony/stopwatch": "^5.4 || ^6.0" }, "require-dev": { "justinrainbow/json-schema": "^5.2", - "keradus/cli-executor": "^1.5", - "mikey179/vfsstream": "^1.6.8", - "php-coveralls/php-coveralls": "^2.5.2", + "keradus/cli-executor": "^2.0", + "mikey179/vfsstream": "^1.6.11", + "php-coveralls/php-coveralls": "^2.5.3", "php-cs-fixer/accessible-object": "^1.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy": "^1.15", - "phpspec/prophecy-phpunit": "^1.1 || ^2.0", - "phpunit/phpunit": "^8.5.21 || ^9.5", - "phpunitgoodpractices/polyfill": "^1.5", - "phpunitgoodpractices/traits": "^1.9.1", - "symfony/phpunit-bridge": "^5.2.4 || ^6.0", - "symfony/yaml": "^4.4.20 || ^5.0 || ^6.0" + "phpspec/prophecy": "^1.16", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "phpunitgoodpractices/polyfill": "^1.6", + "phpunitgoodpractices/traits": "^1.9.2", + "symfony/phpunit-bridge": "^6.2.3", + "symfony/yaml": "^5.4 || ^6.0" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -4058,9 +4064,15 @@ } ], "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], "support": { - "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", - "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.4.0" + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.15.1" }, "funding": [ { @@ -4068,60 +4080,7 @@ "type": "github" } ], - "time": "2021-12-11T16:25:08+00:00" - }, - { - "name": "php-cs-fixer/diff", - "version": "v2.0.2", - "source": { - "type": "git", - "url": "https://github.com/PHP-CS-Fixer/diff.git", - "reference": "29dc0d507e838c4580d018bd8b5cb412474f7ec3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/29dc0d507e838c4580d018bd8b5cb412474f7ec3", - "reference": "29dc0d507e838c4580d018bd8b5cb412474f7ec3", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7.23 || ^6.4.3 || ^7.0", - "symfony/process": "^3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "sebastian/diff v3 backport support for PHP 5.6+", - "homepage": "https://github.com/PHP-CS-Fixer", - "keywords": [ - "diff" - ], - "support": { - "issues": "https://github.com/PHP-CS-Fixer/diff/issues", - "source": "https://github.com/PHP-CS-Fixer/diff/tree/v2.0.2" - }, - "abandoned": true, - "time": "2020-10-14T08:32:19+00:00" + "time": "2023-03-13T23:26:30+00:00" }, { "name": "php-parallel-lint/php-parallel-lint", @@ -4182,16 +4141,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.8", + "version": "1.10.9", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "0166aef76e066f0dd2adc2799bdadfa1635711e9" + "reference": "9b13dafe3d66693d20fe5729c3dde1d31bb64703" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0166aef76e066f0dd2adc2799bdadfa1635711e9", - "reference": "0166aef76e066f0dd2adc2799bdadfa1635711e9", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9b13dafe3d66693d20fe5729c3dde1d31bb64703", + "reference": "9b13dafe3d66693d20fe5729c3dde1d31bb64703", "shasum": "" }, "require": { @@ -4240,7 +4199,7 @@ "type": "tidelift" } ], - "time": "2023-03-24T10:28:16+00:00" + "time": "2023-03-30T08:58:01+00:00" }, { "name": "psr/event-dispatcher", @@ -4292,18 +4251,84 @@ }, "time": "2019-01-08T18:20:26+00:00" }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, { "name": "symfony/console", - "version": "v5.4.21", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "c77433ddc6cdc689caf48065d9ea22ca0853fbd9" + "reference": "3cd51fd2e6c461ca678f84d419461281bd87a0a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/c77433ddc6cdc689caf48065d9ea22ca0853fbd9", - "reference": "c77433ddc6cdc689caf48065d9ea22ca0853fbd9", + "url": "https://api.github.com/repos/symfony/console/zipball/3cd51fd2e6c461ca678f84d419461281bd87a0a8", + "reference": "3cd51fd2e6c461ca678f84d419461281bd87a0a8", "shasum": "" }, "require": { @@ -4368,12 +4393,12 @@ "homepage": "https://symfony.com", "keywords": [ "cli", - "command line", + "command-line", "console", "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.21" + "source": "https://github.com/symfony/console/tree/v5.4.22" }, "funding": [ { @@ -4389,20 +4414,20 @@ "type": "tidelift" } ], - "time": "2023-02-25T16:59:41+00:00" + "time": "2023-03-25T09:27:28+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v5.4.21", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "f0ae1383a8285dfc6752b8d8602790953118ff5a" + "reference": "1df20e45d56da29a4b1d8259dd6e950acbf1b13f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f0ae1383a8285dfc6752b8d8602790953118ff5a", - "reference": "f0ae1383a8285dfc6752b8d8602790953118ff5a", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1df20e45d56da29a4b1d8259dd6e950acbf1b13f", + "reference": "1df20e45d56da29a4b1d8259dd6e950acbf1b13f", "shasum": "" }, "require": { @@ -4458,7 +4483,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.21" + "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.22" }, "funding": [ { @@ -4474,7 +4499,7 @@ "type": "tidelift" } ], - "time": "2023-02-14T08:03:56+00:00" + "time": "2023-03-17T11:31:58+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -5030,16 +5055,16 @@ }, { "name": "symfony/process", - "version": "v5.4.21", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "d4ce417ebcb0b7d090b4c178ed6d3accc518e8bd" + "reference": "4b850da0cc3a2a9181c1ed407adbca4733dc839b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/d4ce417ebcb0b7d090b4c178ed6d3accc518e8bd", - "reference": "d4ce417ebcb0b7d090b4c178ed6d3accc518e8bd", + "url": "https://api.github.com/repos/symfony/process/zipball/4b850da0cc3a2a9181c1ed407adbca4733dc839b", + "reference": "4b850da0cc3a2a9181c1ed407adbca4733dc839b", "shasum": "" }, "require": { @@ -5072,7 +5097,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.21" + "source": "https://github.com/symfony/process/tree/v5.4.22" }, "funding": [ { @@ -5088,7 +5113,7 @@ "type": "tidelift" } ], - "time": "2023-02-21T19:46:44+00:00" + "time": "2023-03-06T21:29:33+00:00" }, { "name": "symfony/stopwatch", @@ -5154,16 +5179,16 @@ }, { "name": "symfony/string", - "version": "v5.4.21", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "edac10d167b78b1d90f46a80320d632de0bd9f2f" + "reference": "8036a4c76c0dd29e60b6a7cafcacc50cf088ea62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/edac10d167b78b1d90f46a80320d632de0bd9f2f", - "reference": "edac10d167b78b1d90f46a80320d632de0bd9f2f", + "url": "https://api.github.com/repos/symfony/string/zipball/8036a4c76c0dd29e60b6a7cafcacc50cf088ea62", + "reference": "8036a4c76c0dd29e60b6a7cafcacc50cf088ea62", "shasum": "" }, "require": { @@ -5220,7 +5245,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.21" + "source": "https://github.com/symfony/string/tree/v5.4.22" }, "funding": [ { @@ -5236,7 +5261,7 @@ "type": "tidelift" } ], - "time": "2023-02-22T08:00:55+00:00" + "time": "2023-03-14T06:11:53+00:00" } ], "aliases": [], @@ -5245,12 +5270,12 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">= 7.2.5", + "php": ">= 7.4.0", "ext-gd": "*" }, "platform-dev": [], "platform-overrides": { - "php": "7.2.5" + "php": "7.4.0" }, "plugin-api-version": "2.3.0" } diff --git a/docs/content/docs/administration/requirements.md b/docs/content/docs/administration/requirements.md index 80dac53e86..1e61145a5b 100644 --- a/docs/content/docs/administration/requirements.md +++ b/docs/content/docs/administration/requirements.md @@ -6,7 +6,7 @@ extra.show_next = true selfoss is not a hosted service. It has to be installed on your own web server. This web server must fulfil the following requirements (which are available from most providers) -* PHP 5.6 or higher with the `php-gd` and `php-http` extensions enabled. Some spouts may also require `curl`, `mbstring` or `tidy` extensions. The `php-imagick` extension is required if you want selfoss to support SVG site icons. +* PHP 7.4.0 or higher with the `php-gd` and `php-http` extensions enabled. Some spouts may also require `curl`, `mbstring` or `tidy` extensions. The `php-imagick` extension is required if you want selfoss to support SVG site icons. * MySQL 5.5.3 or higher, PostgreSQL, or SQLite * Apache web server (nginx and Lighttpd also possible) diff --git a/docs/content/docs/customization/spouts/index.md b/docs/content/docs/customization/spouts/index.md index 1fa9a745bf..d8e7ad743c 100644 --- a/docs/content/docs/customization/spouts/index.md +++ b/docs/content/docs/customization/spouts/index.md @@ -32,9 +32,9 @@ namespace spouts\Mail; use spouts\Parameter; class Imap extends \spouts\spout { - public $name = 'E-mail'; - public $description = 'Obtain e-mails from IMAP account'; - public $params = [ + public string $name = 'E-mail'; + public string $description = 'Obtain e-mails from IMAP account'; + public array $params = [ 'email' => [ 'title' => 'E-mail', 'type' => Parameter::TYPE_TEXT, diff --git a/phpstan.neon b/phpstan.neon index 480af97e6a..32d3d834f9 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -22,7 +22,6 @@ parameters: # Bad PHPStan typing rules. - '(Parameter #3 \$namespace of method XMLWriter::writeAttributeNs\(\) expects string, null given\.)' - - '(Parameter #2 \$algo of function password_hash expects int, string given\.)' # Only fails on PHP ≥ 7.4 typeAliases: SpoutParameterInfo: 'array{title: string, type: spouts\Parameter::TYPE_*, default: string, required: bool, validation: array, values?: array}' diff --git a/src/common.php b/src/common.php index ada85b09c6..5e7a1fad0b 100644 --- a/src/common.php +++ b/src/common.php @@ -58,9 +58,7 @@ function boot_error(string $message) { 'substitutions' => [ // Instantiate configuration container. Configuration::class => [ - Dice::INSTANCE => function() use ($configuration) { - return $configuration; - }, + Dice::INSTANCE => fn() => $configuration, 'shared' => true, ], @@ -268,7 +266,8 @@ function(string $pattern, string $text): bool { } // init error handling -$f3->set('ONERROR', +$f3->set( + 'ONERROR', function(Base $f3) use ($configuration, $log, $handler): void { $exception = $f3->get('EXCEPTION'); @@ -280,7 +279,7 @@ function(Base $f3) use ($configuration, $log, $handler): void { } if ($configuration->debug !== 0) { - echo 'An error occurred' . ': '; + echo 'An error occurred: '; echo $f3->get('ERROR.text') . "\n"; echo $f3->get('ERROR.trace'); } else { diff --git a/src/controllers/About.php b/src/controllers/About.php index 77d7b4f04f..5e0af5f716 100644 --- a/src/controllers/About.php +++ b/src/controllers/About.php @@ -12,14 +12,9 @@ * Controller for instance information API */ class About { - /** @var Authentication authentication helper */ - private $authentication; - - /** @var Configuration configuration */ - private $configuration; - - /** @var View view helper */ - private $view; + private Authentication $authentication; + private Configuration $configuration; + private View $view; public function __construct(Authentication $authentication, Configuration $configuration, View $view) { $this->authentication = $authentication; diff --git a/src/controllers/Authentication.php b/src/controllers/Authentication.php index c5191f1a93..bafd37776e 100644 --- a/src/controllers/Authentication.php +++ b/src/controllers/Authentication.php @@ -11,11 +11,8 @@ * Controller for user related tasks */ class Authentication { - /** @var helpers\Authentication authentication helper */ - private $authentication; - - /** @var View view helper */ - private $view; + private helpers\Authentication $authentication; + private View $view; public function __construct(helpers\Authentication $authentication, View $view) { $this->authentication = $authentication; diff --git a/src/controllers/Helpers/HashPassword.php b/src/controllers/Helpers/HashPassword.php index 82fb87feb3..77998797d1 100644 --- a/src/controllers/Helpers/HashPassword.php +++ b/src/controllers/Helpers/HashPassword.php @@ -11,11 +11,8 @@ * Controller for user related tasks */ final class HashPassword { - /** @var Authentication authentication helper */ - private $authentication; - - /** @var View view helper */ - private $view; + private Authentication $authentication; + private View $view; public function __construct(Authentication $authentication, View $view) { $this->authentication = $authentication; diff --git a/src/controllers/Index.php b/src/controllers/Index.php index 768bc75d6d..edc18e8401 100644 --- a/src/controllers/Index.php +++ b/src/controllers/Index.php @@ -18,29 +18,14 @@ * @author Tobias Zeising */ class Index { - /** @var Authentication authentication helper */ - private $authentication; - - /** @var \daos\Items items */ - private $itemsDao; - - /** @var Router router */ - private $router; - - /** @var \daos\Sources sources */ - private $sourcesDao; - - /** @var \controllers\Tags tags controller */ - private $tagsController; - - /** @var \daos\Tags tags */ - private $tagsDao; - - /** @var View view helper */ - private $view; - - /** @var ViewHelper */ - private $viewHelper; + private Authentication $authentication; + private \daos\Items $itemsDao; + private Router $router; + private \daos\Sources $sourcesDao; + private Tags $tagsController; + private \daos\Tags $tagsDao; + private View $view; + private ViewHelper $viewHelper; public function __construct(Authentication $authentication, \daos\Items $itemsDao, Router $router, \daos\Sources $sourcesDao, Tags $tagsController, \daos\Tags $tagsDao, View $view, ViewHelper $viewHelper) { $this->authentication = $authentication; diff --git a/src/controllers/Items.php b/src/controllers/Items.php index b803acdfb5..ff8c6cefc5 100644 --- a/src/controllers/Items.php +++ b/src/controllers/Items.php @@ -5,6 +5,7 @@ namespace controllers; use daos\ItemOptions; +use DateTimeInterface; use helpers\Authentication; use helpers\Misc; use helpers\Request; @@ -19,17 +20,10 @@ * @author Tobias Zeising */ class Items { - /** @var Authentication authentication helper */ - private $authentication; - - /** @var \daos\Items items */ - private $itemsDao; - - /** @var Request */ - private $request; - - /** @var View view helper */ - private $view; + private Authentication $authentication; + private \daos\Items $itemsDao; + private Request $request; + private View $view; public function __construct( Authentication $authentication, @@ -162,8 +156,8 @@ public function listItems(): void { $items = array_map(function(array $item) { $stringifiedDates = [ - 'datetime' => $item['datetime']->format(\DateTime::ATOM), - 'updatetime' => $item['updatetime']->format(\DateTime::ATOM), + 'datetime' => $item['datetime']->format(DateTimeInterface::ATOM), + 'updatetime' => $item['updatetime']->format(DateTimeInterface::ATOM), ]; return array_merge($item, $stringifiedDates); diff --git a/src/controllers/Items/Stats.php b/src/controllers/Items/Stats.php index 0a331f70b0..2454a50925 100644 --- a/src/controllers/Items/Stats.php +++ b/src/controllers/Items/Stats.php @@ -11,20 +11,11 @@ * Controller for viewing item statistics */ class Stats { - /** @var Authentication authentication helper */ - private $authentication; - - /** @var \daos\Items items */ - private $itemsDao; - - /** @var \daos\Sources sources */ - private $sourcesDao; - - /** @var \daos\Tags tags */ - private $tagsDao; - - /** @var View view helper */ - private $view; + private Authentication $authentication; + private \daos\Items $itemsDao; + private \daos\Sources $sourcesDao; + private \daos\Tags $tagsDao; + private View $view; public function __construct(Authentication $authentication, \daos\Items $itemsDao, \daos\Sources $sourcesDao, \daos\Tags $tagsDao, View $view) { $this->authentication = $authentication; diff --git a/src/controllers/Items/Sync.php b/src/controllers/Items/Sync.php index 0906a37534..6e0fa8b455 100644 --- a/src/controllers/Items/Sync.php +++ b/src/controllers/Items/Sync.php @@ -14,29 +14,14 @@ * Controller for synchronizing item statuses */ class Sync { - /** @var Authentication authentication helper */ - private $authentication; - - /** @var Configuration configuration */ - private $configuration; - - /** @var \daos\Items items */ - private $itemsDao; - - /** @var \daos\Sources sources */ - private $sourcesDao; - - /** @var \controllers\Tags tags controller */ - private $tagsController; - - /** @var \daos\Tags tags */ - private $tagsDao; - - /** @var View view helper */ - private $view; - - /** @var ViewHelper */ - private $viewHelper; + private Authentication $authentication; + private Configuration $configuration; + private \daos\Items $itemsDao; + private \daos\Sources $sourcesDao; + private \controllers\Tags $tagsController; + private \daos\Tags $tagsDao; + private View $view; + private ViewHelper $viewHelper; public function __construct(Authentication $authentication, Configuration $configuration, \daos\Items $itemsDao, \daos\Sources $sourcesDao, \controllers\Tags $tagsController, \daos\Tags $tagsDao, View $view, ViewHelper $viewHelper) { $this->authentication = $authentication; @@ -89,8 +74,10 @@ public function sync(): void { $itemsHowMany = $this->configuration->itemsPerpage; if (array_key_exists('itemsHowMany', $params) && is_int($params['itemsHowMany'])) { - $itemsHowMany = min($params['itemsHowMany'], - 2 * $itemsHowMany); + $itemsHowMany = min( + $params['itemsHowMany'], + 2 * $itemsHowMany + ); } $sync['newItems'] = function() use ($sinceId, $notBefore, $since, $itemsHowMany) { diff --git a/src/controllers/Opml/Export.php b/src/controllers/Opml/Export.php index 4b655f9935..e96bf87119 100644 --- a/src/controllers/Opml/Export.php +++ b/src/controllers/Opml/Export.php @@ -18,26 +18,13 @@ * @author Sean Rand */ class Export { - /** @var Authentication authentication helper */ - private $authentication; - - /** @var Configuration configuration */ - private $configuration; - - /** @var Logger */ - private $logger; - - /** @var SpoutLoader */ - private $spoutLoader; - - /** @var \XMLWriter */ - private $writer; - - /** @var \daos\Sources */ - private $sourcesDao; - - /** @var \daos\Tags */ - private $tagsDao; + private Authentication $authentication; + private Configuration $configuration; + private Logger $logger; + private SpoutLoader $spoutLoader; + private \XMLWriter $writer; + private \daos\Sources $sourcesDao; + private \daos\Tags $tagsDao; public function __construct(Authentication $authentication, Configuration $configuration, Logger $logger, \daos\Sources $sourcesDao, SpoutLoader $spoutLoader, \daos\Tags $tagsDao, \XMLWriter $writer) { $this->authentication = $authentication; diff --git a/src/controllers/Opml/Import.php b/src/controllers/Opml/Import.php index 9718e434d8..e9ceb8e540 100644 --- a/src/controllers/Opml/Import.php +++ b/src/controllers/Opml/Import.php @@ -18,23 +18,14 @@ * @author Sean Rand */ class Import { - /** @var Authentication authentication helper */ - private $authentication; - /** @var array Sources that have been imported from the OPML file */ - private $imported = []; - - /** @var Logger */ - private $logger; - - /** @var \daos\Sources */ - private $sourcesDao; - - /** @var \daos\Tags */ - private $tagsDao; + private array $imported = []; - /** @var View view helper */ - private $view; + private Authentication $authentication; + private Logger $logger; + private \daos\Sources $sourcesDao; + private \daos\Tags $tagsDao; + private View $view; public function __construct(Authentication $authentication, Logger $logger, \daos\Sources $sourcesDao, \daos\Tags $tagsDao, View $view) { $this->authentication = $authentication; diff --git a/src/controllers/Opml/ImportPage.php b/src/controllers/Opml/ImportPage.php index f8a181426b..f8728860c4 100644 --- a/src/controllers/Opml/ImportPage.php +++ b/src/controllers/Opml/ImportPage.php @@ -12,8 +12,7 @@ * @TODO move this into JS client */ class ImportPage { - /** @var Authentication authentication helper */ - private $authentication; + private Authentication $authentication; public function __construct(Authentication $authentication) { $this->authentication = $authentication; diff --git a/src/controllers/Rss.php b/src/controllers/Rss.php index 89d8f0181b..b460baaa13 100644 --- a/src/controllers/Rss.php +++ b/src/controllers/Rss.php @@ -18,23 +18,12 @@ * @author Tobias Zeising */ class Rss { - /** @var Authentication authentication helper */ - private $authentication; - - /** @var Configuration configuration */ - private $configuration; - - /** @var RSS2 feed writer */ - private $feedWriter; - - /** @var \daos\Items items */ - private $itemsDao; - - /** @var \daos\Sources sources */ - private $sourcesDao; - - /** @var View view helper */ - private $view; + private Authentication $authentication; + private Configuration $configuration; + private RSS2 $feedWriter; + private \daos\Items $itemsDao; + private \daos\Sources $sourcesDao; + private View $view; public function __construct(Authentication $authentication, Configuration $configuration, RSS2 $feedWriter, \daos\Items $itemsDao, \daos\Sources $sourcesDao, View $view) { $this->authentication = $authentication; diff --git a/src/controllers/Sources.php b/src/controllers/Sources.php index b2b80c8641..0490a5850c 100644 --- a/src/controllers/Sources.php +++ b/src/controllers/Sources.php @@ -18,20 +18,11 @@ * @author Tobias Zeising */ class Sources { - /** @var Authentication authentication helper */ - private $authentication; - - /** @var \daos\Sources sources */ - private $sourcesDao; - - /** @var SpoutLoader spout loader */ - private $spoutLoader; - - /** @var \daos\Tags tags */ - private $tagsDao; - - /** @var View view helper */ - private $view; + private Authentication $authentication; + private \daos\Sources $sourcesDao; + private SpoutLoader $spoutLoader; + private \daos\Tags $tagsDao; + private View $view; public function __construct(Authentication $authentication, \daos\Sources $sourcesDao, SpoutLoader $spoutLoader, \daos\Tags $tagsDao, View $view) { $this->authentication = $authentication; diff --git a/src/controllers/Sources/Update.php b/src/controllers/Sources/Update.php index 662326ba20..a07bfe2c5b 100644 --- a/src/controllers/Sources/Update.php +++ b/src/controllers/Sources/Update.php @@ -14,14 +14,9 @@ * Controller updating sources */ class Update { - /** @var Authentication authentication helper */ - private $authentication; - - /** @var ContentLoader content loader */ - private $contentLoader; - - /** @var View view helper */ - private $view; + private Authentication $authentication; + private ContentLoader $contentLoader; + private View $view; public function __construct( Authentication $authentication, diff --git a/src/controllers/Sources/Write.php b/src/controllers/Sources/Write.php index 763f8ad849..89219a978c 100644 --- a/src/controllers/Sources/Write.php +++ b/src/controllers/Sources/Write.php @@ -18,26 +18,13 @@ * Controller for creating and editing sources */ class Write { - /** @var Authentication authentication helper */ - private $authentication; - - /** @var ContentLoader content loader */ - private $contentLoader; - - /** @var Request */ - private $request; - - /** @var \daos\Sources sources */ - private $sourcesDao; - - /** @var SpoutLoader spout loader */ - private $spoutLoader; - - /** @var \daos\Tags tags */ - private $tagsDao; - - /** @var View view helper */ - private $view; + private Authentication $authentication; + private ContentLoader $contentLoader; + private \helpers\Request $request; + private \daos\Sources $sourcesDao; + private SpoutLoader $spoutLoader; + private \daos\Tags $tagsDao; + private View $view; public function __construct( Authentication $authentication, diff --git a/src/controllers/Tags.php b/src/controllers/Tags.php index efbfe50c56..84ffff2c14 100644 --- a/src/controllers/Tags.php +++ b/src/controllers/Tags.php @@ -16,17 +16,13 @@ * @author Tobias Zeising */ class Tags { - /** @var Authentication authentication helper */ - private $authentication; - - /** @var Request */ - private $request; - - /** @var \daos\Tags tags */ - private $tagsDao; + /** @var ?array cache of tags and associated colors */ + protected ?array $tagsColors = null; - /** @var View view helper */ - private $view; + private Authentication $authentication; + private Request $request; + private \daos\Tags $tagsDao; + private View $view; public function __construct( Authentication $authentication, @@ -40,9 +36,6 @@ public function __construct( $this->view = $view; } - /** @var ?array cache of tags and associated colors */ - protected $tagsColors = null; - /** * returns item tags as HTML * diff --git a/src/daos/ItemOptions.php b/src/daos/ItemOptions.php index 2258b64a14..0bb56489b5 100644 --- a/src/daos/ItemOptions.php +++ b/src/daos/ItemOptions.php @@ -10,35 +10,43 @@ * Object holding parameters for querying items. */ final class ItemOptions { - /** @var ?int @readonly */ - public $offset = 0; + /** @readonly */ + public ?int $offset = 0; - /** @var ?string @readonly */ - public $search = null; + /** @readonly */ + public ?string $search = null; - /** @var ?int maximum number of items to fetch from the database (unbounded) @readonly */ - public $pageSize = null; + /** + * Maximum number of items to fetch from the database (unbounded) + * + * @readonly + */ + public ?int $pageSize = null; - /** @var ?DateTime @readonly */ - public $fromDatetime = null; + /** @readonly */ + public ?DateTime $fromDatetime = null; - /** @var ?int @readonly */ - public $fromId = null; + /** @readonly */ + public ?int $fromId = null; - /** @var ?DateTime @readonly */ - public $updatedSince = null; + /** @readonly */ + public ?DateTime $updatedSince = null; - /** @var ?string @readonly */ - public $tag = null; + /** @readonly */ + public ?string $tag = null; - /** @var 'starred'|'unread'|null @readonly */ - public $filter = null; + /** + * @var 'starred'|'unread'|null + * + * @readonly + */ + public ?string $filter = null; - /** @var ?int @readonly */ - public $source = null; + /** @readonly */ + public ?int $source = null; /** @var int[] @readonly */ - public $extraIds = []; + public array $extraIds = []; /** * Creates new ItemOptions object ensuring the values are proper types. @@ -87,9 +95,10 @@ public static function fromUser(array $data): self { } if (isset($data['extraIds']) && is_array($data['extraIds'])) { - $options->extraIds = array_map(function($val) { - return (int) $val; - }, $data['extraIds']); + $options->extraIds = array_map( + fn($val) => (int) $val, + $data['extraIds'] + ); } return $options; diff --git a/src/daos/Items.php b/src/daos/Items.php index a406da307c..533174d73f 100644 --- a/src/daos/Items.php +++ b/src/daos/Items.php @@ -17,11 +17,8 @@ * @author Tobias Zeising */ class Items implements ItemsInterface { - /** @var ItemsInterface Instance of backend specific items class */ - private $backend; - - /** @var Authentication authentication helper */ - private $authentication; + private Authentication $authentication; + private ItemsInterface $backend; public function __construct( Authentication $authentication, diff --git a/src/daos/Sources.php b/src/daos/Sources.php index 081c35011e..6114a46472 100644 --- a/src/daos/Sources.php +++ b/src/daos/Sources.php @@ -18,14 +18,9 @@ * @author Tobias Zeising */ class Sources implements SourcesInterface { - /** @var SourcesInterface Instance of backend specific sources class */ - private $backend; - - /** @var Authentication authentication helper */ - private $authentication; - - /** @var SpoutLoader spout loader */ - private $spoutLoader; + private Authentication $authentication; + private SourcesInterface $backend; + private SpoutLoader $spoutLoader; public function __construct( Authentication $authentication, diff --git a/src/daos/Tags.php b/src/daos/Tags.php index 875cf93e1e..c72efb57b3 100644 --- a/src/daos/Tags.php +++ b/src/daos/Tags.php @@ -14,11 +14,9 @@ * Proxy for accessing tag colors. */ class Tags implements TagsInterface { - /** @var TagsInterface Instance of backend-specific Tags class */ - private $backend; - - /** @var Authentication */ - private $authentication; + private Authentication $authentication; + /** Instance of backend-specific Tags class */ + private TagsInterface $backend; public function __construct( Authentication $authentication, diff --git a/src/daos/mysql/Database.php b/src/daos/mysql/Database.php index 1ea2c3b565..b597b90c20 100644 --- a/src/daos/mysql/Database.php +++ b/src/daos/mysql/Database.php @@ -18,11 +18,8 @@ class Database implements \daos\DatabaseInterface { use CommonSqlDatabase; - /** @var DatabaseConnection database connection */ - private $connection; - - /** @var Logger */ - private $logger; + private DatabaseConnection $connection; + private Logger $logger; /** * establish connection and diff --git a/src/daos/mysql/Items.php b/src/daos/mysql/Items.php index 23af884b87..f8b3e4d687 100644 --- a/src/daos/mysql/Items.php +++ b/src/daos/mysql/Items.php @@ -21,20 +21,15 @@ * @author Harald Lapp */ class Items implements \daos\ItemsInterface { - /** @var bool indicates whether last run has more results or not */ - protected $hasMore = false; + /** Indicates whether last run has more results or not */ + protected bool $hasMore = false; /** @var class-string SQL helper */ - protected static $stmt = Statements::class; + protected static string $stmt = Statements::class; - /** @var Configuration configuration */ - private $configuration; - - /** @var DatabaseInterface database connection */ - protected $database; - - /** @var Logger */ - private $logger; + private Logger $logger; + private Configuration $configuration; + protected DatabaseInterface $database; public function __construct(Logger $logger, Configuration $configuration, DatabaseInterface $database) { $this->configuration = $configuration; @@ -51,9 +46,7 @@ public function mark(array $ids): void { $ids = implode( ',', array_map( - function(int $id): string { - return (string) $id; - }, + fn(int $id): string => (string) $id, $ids ) ); @@ -74,9 +67,7 @@ public function unmark(array $ids): void { $ids = implode( ',', array_map( - function(int $id): string { - return (string) $id; - }, + fn(int $id): string => (string) $id, $ids ) ); @@ -118,44 +109,46 @@ public function unstarr(int $id): void { * @param array{datetime: \DateTimeInterface, title: HtmlString, content: HtmlString, thumbnail: ?string, icon: ?string, source: int, uid: string, link: string, author: ?string} $values */ public function add(array $values): void { - $this->database->exec('INSERT INTO ' . $this->configuration->dbPrefix . 'items ( - datetime, - title, - content, - unread, - starred, - source, - thumbnail, - icon, - uid, - link, - author - ) VALUES ( - :datetime, - :title, - :content, - :unread, - :starred, - :source, - :thumbnail, - :icon, - :uid, - :link, - :author - )', - [ - ':datetime' => $values['datetime']->format('Y-m-d H:i:s'), - ':title' => $values['title']->getRaw(), - ':content' => $values['content']->getRaw(), - ':thumbnail' => $values['thumbnail'], - ':icon' => $values['icon'], - ':unread' => 1, - ':starred' => 0, - ':source' => $values['source'], - ':uid' => $values['uid'], - ':link' => $values['link'], - ':author' => $values['author'], - ]); + $this->database->exec( + 'INSERT INTO ' . $this->configuration->dbPrefix . 'items ( + datetime, + title, + content, + unread, + starred, + source, + thumbnail, + icon, + uid, + link, + author + ) VALUES ( + :datetime, + :title, + :content, + :unread, + :starred, + :source, + :thumbnail, + :icon, + :uid, + :link, + :author + )', + [ + ':datetime' => $values['datetime']->format('Y-m-d H:i:s'), + ':title' => $values['title']->getRaw(), + ':content' => $values['content']->getRaw(), + ':thumbnail' => $values['thumbnail'], + ':icon' => $values['icon'], + ':unread' => 1, + ':starred' => 0, + ':source' => $values['source'], + ':uid' => $values['uid'], + ':link' => $values['link'], + ':author' => $values['author'], + ] + ); } /** @@ -163,8 +156,10 @@ public function add(array $values): void { * uid exists or not */ public function exists(string $uid): bool { - $res = $this->database->exec('SELECT COUNT(*) AS amount FROM ' . $this->configuration->dbPrefix . 'items WHERE uid=:uid', - [':uid' => [$uid, \PDO::PARAM_STR]]); + $res = $this->database->exec( + 'SELECT COUNT(*) AS amount FROM ' . $this->configuration->dbPrefix . 'items WHERE uid=:uid', + [':uid' => [$uid, \PDO::PARAM_STR]] + ); return $res[0]['amount'] > 0; } @@ -183,9 +178,10 @@ public function findAll(array $itemsInFeed, int $sourceId): array { return $itemsFound; } - $itemsInFeed = array_map(function(string $uid): string { - return $this->database->quote($uid); - }, $itemsInFeed); + $itemsInFeed = array_map( + fn(string $uid): string => $this->database->quote($uid), + $itemsInFeed + ); $query = 'SELECT id, uid AS uid FROM ' . $this->configuration->dbPrefix . 'items WHERE source = ' . $this->database->quote($sourceId) . ' AND uid IN (' . implode(',', $itemsInFeed) . ')'; /** @var array $result */ $result = $this->database->exec($query); @@ -217,9 +213,10 @@ public function cleanup(?DateTime $date): void { WHERE source NOT IN ( SELECT id FROM ' . $this->configuration->dbPrefix . 'sources)'); if ($date !== null) { - $this->database->exec('DELETE FROM ' . $this->configuration->dbPrefix . 'items + $this->database->exec( + 'DELETE FROM ' . $this->configuration->dbPrefix . 'items WHERE ' . static::$stmt::isFalse('starred') . ' AND lastseen<:date', - [':date' => $date->format('Y-m-d') . ' 00:00:00'] + [':date' => $date->format('Y-m-d') . ' 00:00:00'] ); } } @@ -425,7 +422,8 @@ public function lowestIdOfInterest(): int { 'SELECT id FROM ' . $this->configuration->dbPrefix . 'items AS items WHERE ' . static::$stmt::isTrue('unread') . ' OR ' . static::$stmt::isTrue('starred') . - ' ORDER BY id LIMIT 1'), + ' ORDER BY id LIMIT 1' + ), ['id' => DatabaseInterface::PARAM_INT] ); if ($lowest) { @@ -444,7 +442,8 @@ public function lastId(): int { $lastId = static::$stmt::ensureRowTypes( $this->database->exec( 'SELECT id FROM ' . $this->configuration->dbPrefix . 'items AS items - ORDER BY id DESC LIMIT 1'), + ORDER BY id DESC LIMIT 1' + ), ['id' => DatabaseInterface::PARAM_INT] ); if ($lastId) { @@ -496,10 +495,12 @@ public function getIcons(): array { * @return bool true if thumbnail is still in use */ public function hasThumbnail(string $thumbnail): bool { - $res = $this->database->exec('SELECT count(*) AS amount + $res = $this->database->exec( + 'SELECT count(*) AS amount FROM ' . $this->configuration->dbPrefix . 'items WHERE thumbnail=:thumbnail', - [':thumbnail' => $thumbnail]); + [':thumbnail' => $thumbnail] + ); $amount = $res[0]['amount']; if ($amount == 0) { $this->logger->debug('thumbnail not found: ' . $thumbnail); @@ -516,10 +517,12 @@ public function hasThumbnail(string $thumbnail): bool { * @return bool true if icon is still in use */ public function hasIcon(string $icon): bool { - $res = $this->database->exec('SELECT count(*) AS amount + $res = $this->database->exec( + 'SELECT count(*) AS amount FROM ' . $this->configuration->dbPrefix . 'items WHERE icon=:icon', - [':icon' => $icon]); + [':icon' => $icon] + ); return $res[0]['amount'] > 0; } @@ -577,10 +580,12 @@ public function lastUpdate(): ?DateTimeImmutable { * @return array of unread, starred, etc. status of specified items */ public function statuses(DateTime $since): array { - $res = $this->database->exec('SELECT id, unread, starred + $res = $this->database->exec( + 'SELECT id, unread, starred FROM ' . $this->configuration->dbPrefix . 'items WHERE ' . $this->configuration->dbPrefix . 'items.updatetime > :since;', - [':since' => [$since->format('Y-m-d H:i:s'), \PDO::PARAM_STR]]); + [':since' => [$since->format('Y-m-d H:i:s'), \PDO::PARAM_STR]] + ); $res = static::$stmt::ensureRowTypes($res, [ 'id' => DatabaseInterface::PARAM_INT, 'unread' => DatabaseInterface::PARAM_BOOL, @@ -662,7 +667,9 @@ public function bulkStatusUpdate(array $statuses): void { $updated = $this->database->execute( 'UPDATE ' . $this->configuration->dbPrefix . 'items SET ' . implode(', ', array_values($q['updates'])) . ' - WHERE id = :id AND updatetime < :statusUpdate', $params); + WHERE id = :id AND updatetime < :statusUpdate', + $params + ); if ($updated->rowCount() === 0) { // entry status was updated in between so updatetime must // be updated to ensure client side consistency of @@ -670,7 +677,9 @@ public function bulkStatusUpdate(array $statuses): void { $this->database->exec( 'UPDATE ' . $this->configuration->dbPrefix . 'items SET ' . static::$stmt::rowTouch('updatetime') . ' - WHERE id = :id', [':id' => [$id, \PDO::PARAM_INT]]); + WHERE id = :id', + [':id' => [$id, \PDO::PARAM_INT]] + ); } } $this->database->commit(); diff --git a/src/daos/mysql/Sources.php b/src/daos/mysql/Sources.php index 07badb4793..62e125b9dd 100644 --- a/src/daos/mysql/Sources.php +++ b/src/daos/mysql/Sources.php @@ -21,13 +21,10 @@ */ class Sources implements \daos\SourcesInterface { /** @var class-string SQL helper */ - protected static $stmt = Statements::class; + protected static string $stmt = Statements::class; - /** @var Configuration configuration */ - private $configuration; - - /** @var DatabaseInterface database connection */ - protected $database; + private Configuration $configuration; + protected DatabaseInterface $database; public function __construct(Configuration $configuration, DatabaseInterface $database) { $this->configuration = $configuration; @@ -125,18 +122,22 @@ public function error(int $id, string $error): void { * @param ?int $lastEntry timestamp of the newest item or NULL when no items were added */ public function saveLastUpdate(int $id, ?int $lastEntry): void { - $this->database->exec('UPDATE ' . $this->configuration->dbPrefix . 'sources SET lastupdate=:lastupdate WHERE id=:id', + $this->database->exec( + 'UPDATE ' . $this->configuration->dbPrefix . 'sources SET lastupdate=:lastupdate WHERE id=:id', [ ':id' => $id, ':lastupdate' => time(), - ]); + ] + ); if ($lastEntry !== null) { - $this->database->exec('UPDATE ' . $this->configuration->dbPrefix . 'sources SET lastentry=:lastentry WHERE id=:id', + $this->database->exec( + 'UPDATE ' . $this->configuration->dbPrefix . 'sources SET lastentry=:lastentry WHERE id=:id', [ ':id' => $id, ':lastentry' => $lastEntry, - ]); + ] + ); } } diff --git a/src/daos/mysql/Tags.php b/src/daos/mysql/Tags.php index d86c3b862e..ca6c995f15 100644 --- a/src/daos/mysql/Tags.php +++ b/src/daos/mysql/Tags.php @@ -16,13 +16,10 @@ */ class Tags implements \daos\TagsInterface { /** @var class-string SQL helper */ - protected static $stmt = Statements::class; + protected static string $stmt = Statements::class; - /** @var Configuration configuration */ - private $configuration; - - /** @var DatabaseInterface database connection */ - protected $database; + private Configuration $configuration; + protected DatabaseInterface $database; public function __construct(Configuration $configuration, DatabaseInterface $database) { $this->configuration = $configuration; diff --git a/src/daos/pgsql/Database.php b/src/daos/pgsql/Database.php index c2662fb89d..03f500e488 100644 --- a/src/daos/pgsql/Database.php +++ b/src/daos/pgsql/Database.php @@ -26,11 +26,8 @@ class Database implements \daos\DatabaseInterface { use CommonSqlDatabase; - /** @var DatabaseConnection database connection */ - private $connection; - - /** @var Logger */ - private $logger; + private DatabaseConnection $connection; + private Logger $logger; /** * establish connection and create undefined tables diff --git a/src/daos/pgsql/Items.php b/src/daos/pgsql/Items.php index 1b2d25c36b..047c9eda9e 100644 --- a/src/daos/pgsql/Items.php +++ b/src/daos/pgsql/Items.php @@ -14,5 +14,5 @@ */ class Items extends \daos\mysql\Items { /** @var class-string SQL helper */ - protected static $stmt = Statements::class; + protected static string $stmt = Statements::class; } diff --git a/src/daos/pgsql/Sources.php b/src/daos/pgsql/Sources.php index 5f3f5366e7..76316717ed 100644 --- a/src/daos/pgsql/Sources.php +++ b/src/daos/pgsql/Sources.php @@ -14,5 +14,5 @@ */ class Sources extends \daos\mysql\Sources { /** @var class-string SQL helper */ - protected static $stmt = Statements::class; + protected static string $stmt = Statements::class; } diff --git a/src/daos/pgsql/Tags.php b/src/daos/pgsql/Tags.php index ac82dc42c9..367d7de127 100644 --- a/src/daos/pgsql/Tags.php +++ b/src/daos/pgsql/Tags.php @@ -14,5 +14,5 @@ */ class Tags extends \daos\mysql\Tags { /** @var class-string SQL helper */ - protected static $stmt = Statements::class; + protected static string $stmt = Statements::class; } diff --git a/src/daos/sqlite/Database.php b/src/daos/sqlite/Database.php index 3c359a18a1..8a67a46adc 100644 --- a/src/daos/sqlite/Database.php +++ b/src/daos/sqlite/Database.php @@ -19,11 +19,8 @@ class Database implements \daos\DatabaseInterface { use CommonSqlDatabase; - /** @var DatabaseConnection database connection */ - private $connection; - - /** @var Logger */ - private $logger; + private DatabaseConnection $connection; + private Logger $logger; /** * establish connection and create undefined tables diff --git a/src/daos/sqlite/Items.php b/src/daos/sqlite/Items.php index 71ea66ee62..6b6cf1a9b6 100644 --- a/src/daos/sqlite/Items.php +++ b/src/daos/sqlite/Items.php @@ -14,5 +14,5 @@ */ class Items extends \daos\mysql\Items { /** @var class-string SQL helper */ - protected static $stmt = Statements::class; + protected static string $stmt = Statements::class; } diff --git a/src/daos/sqlite/Sources.php b/src/daos/sqlite/Sources.php index 29a31b62bb..75f4c96c6e 100644 --- a/src/daos/sqlite/Sources.php +++ b/src/daos/sqlite/Sources.php @@ -14,5 +14,5 @@ */ class Sources extends \daos\mysql\Sources { /** @var class-string SQL helper */ - protected static $stmt = Statements::class; + protected static string $stmt = Statements::class; } diff --git a/src/daos/sqlite/Tags.php b/src/daos/sqlite/Tags.php index 0e128ed269..e2a30e26c9 100644 --- a/src/daos/sqlite/Tags.php +++ b/src/daos/sqlite/Tags.php @@ -13,5 +13,5 @@ */ class Tags extends \daos\mysql\Tags { /** @var class-string SQL helper */ - protected static $stmt = Statements::class; + protected static string $stmt = Statements::class; } diff --git a/src/helpers/Authentication.php b/src/helpers/Authentication.php index 079c1319c5..4d18d0cf59 100644 --- a/src/helpers/Authentication.php +++ b/src/helpers/Authentication.php @@ -18,17 +18,11 @@ * Helper class for user authentication. */ class Authentication { - /** @var Configuration configuration */ - private $configuration; + private bool $loggedin = false; - /** @var bool loggedin */ - private $loggedin = false; - - /** @var Logger */ - private $logger; - - /** @var Session */ - private $session; + private Configuration $configuration; + private Logger $logger; + private Session $session; /** * start session and check login diff --git a/src/helpers/Configuration.php b/src/helpers/Configuration.php index 35a32048a6..34091bfed8 100644 --- a/src/helpers/Configuration.php +++ b/src/helpers/Configuration.php @@ -6,6 +6,7 @@ use Exception; use ReflectionClass; +use ReflectionNamedType; /** * Configuration container. @@ -44,152 +45,110 @@ class Configuration { ]; /** @var array Keeps track of options that have been changed. */ - private $modifiedOptions = []; + private array $modifiedOptions = []; // Internal but overridable values. - /** @var int debugging level @internal */ - public $debug = 0; + /** Debugging level @internal */ + public int $debug = 0; - /** @var string @internal */ - public $datadir = __DIR__ . '/../../data'; + /** @internal */ + public string $datadir = __DIR__ . '/../../data'; - /** @var string @internal */ - public $cache = '%datadir%/cache'; + /** @internal */ + public string $cache = '%datadir%/cache'; - /** @var string @internal */ - public $ftrssCustomDataDir = '%datadir%/fulltextrss'; + /** @internal */ + public string $ftrssCustomDataDir = '%datadir%/fulltextrss'; // Rest of the values. - /** @var string */ - public $dbType = 'sqlite'; + public string $dbType = 'sqlite'; - /** @var string */ - public $dbFile = '%datadir%/sqlite/selfoss.db'; + public string $dbFile = '%datadir%/sqlite/selfoss.db'; - /** @var string */ - public $dbHost = 'localhost'; + public string $dbHost = 'localhost'; - /** @var string */ - public $dbDatabase = 'selfoss'; + public string $dbDatabase = 'selfoss'; - /** @var string */ - public $dbUsername = 'root'; + public string $dbUsername = 'root'; - /** @var string */ - public $dbPassword = ''; + public string $dbPassword = ''; - /** @var ?int */ - public $dbPort = null; + public ?int $dbPort = null; - /** @var ?string */ - public $dbSocket = null; + public ?string $dbSocket = null; - /** @var string */ - public $dbPrefix = ''; + public string $dbPrefix = ''; - /** @var string */ - public $loggerDestination = 'file:%datadir%/logs/default.log'; + public string $loggerDestination = 'file:%datadir%/logs/default.log'; /** @var self::LOGGER_LEVEL_* */ - public $loggerLevel = 'ERROR'; + public string $loggerLevel = 'ERROR'; - /** @var int */ - public $itemsPerpage = 50; + public int $itemsPerpage = 50; - /** @var int */ - public $itemsLifetime = 30; + public int $itemsLifetime = 30; - /** @var string */ - public $baseUrl = ''; + public string $baseUrl = ''; - /** @var string */ - public $username = ''; + public string $username = ''; - /** @var string */ - public $password = ''; + public string $password = ''; - /** @var string */ - public $salt = 'lkjl1289'; + public string $salt = 'lkjl1289'; - /** @var bool */ - public $public = false; + public bool $public = false; - /** @var string */ - public $htmlTitle = 'selfoss'; + public string $htmlTitle = 'selfoss'; - /** @var string */ - public $rssTitle = 'selfoss feed'; + public string $rssTitle = 'selfoss feed'; - /** @var int */ - public $rssMaxItems = 300; + public int $rssMaxItems = 300; - /** @var bool */ - public $rssMarkAsRead = false; + public bool $rssMarkAsRead = false; - /** @var string */ - public $homepage = 'newest'; + public string $homepage = 'newest'; - /** @var ?string */ - public $language = null; + public ?string $language = null; - /** @var bool */ - public $autoMarkAsRead = false; + public bool $autoMarkAsRead = false; - /** @var bool */ - public $autoCollapse = false; + public bool $autoCollapse = false; - /** @var bool */ - public $autoStreamMore = true; + public bool $autoStreamMore = true; - /** @var bool */ - public $openInBackgroundTab = false; + public bool $openInBackgroundTab = false; - /** @var string */ - public $share = 'atfpde'; + public string $share = 'atfpde'; - /** @var string */ - public $wallabag = ''; + public string $wallabag = ''; - /** @var string */ - public $wallabagVersion = '2'; + public string $wallabagVersion = '2'; - /** @var ?string */ - public $wordpress = null; + public ?string $wordpress = null; - /** @var ?string */ - public $mastodon = null; + public ?string $mastodon = null; - /** @var bool */ - public $allowPublicUpdateAccess = false; + public bool $allowPublicUpdateAccess = false; - /** @var string */ - public $unreadOrder = 'desc'; + public string $unreadOrder = 'desc'; - /** @var bool */ - public $loadImagesOnMobile = false; + public bool $loadImagesOnMobile = false; - /** @var bool */ - public $autoHideReadOnMobile = false; + public bool $autoHideReadOnMobile = false; - /** @var string */ - public $envPrefix = 'selfoss_'; + public string $envPrefix = 'selfoss_'; - /** @var string */ - public $camoDomain = ''; + public string $camoDomain = ''; - /** @var string */ - public $camoKey = ''; + public string $camoKey = ''; - /** @var bool */ - public $scrollToArticleHeader = true; + public bool $scrollToArticleHeader = true; - /** @var bool */ - public $showThumbnails = true; + public bool $showThumbnails = true; - /** @var int */ - public $readingSpeedWpm = 0; + public int $readingSpeedWpm = 0; /** * @param array $environment @@ -232,14 +191,25 @@ public function __construct(?string $configPath = null, array $environment = []) $value = trim($value); - preg_match('(@var (?P\??)(?P[^\s]+))', $property->getDocComment() ?: '', $matches); - if ($matches['nullable'] === '?' && $value === '') { + $nullable = false; + $propertyType = null; + if (($doc = $property->getDocComment()) !== false && preg_match('(@var (?P\??)(?P[^\s]+))', $doc, $matches) === 1) { + $nullable = $matches['nullable'] === '?'; + $propertyType = $matches['type']; + } else { + $type = $property->getType(); + $nullable = $type !== null && $type->allowsNull(); + if ($type instanceof ReflectionNamedType) { + $propertyType = $type->getName(); + } + } + + if ($nullable && $value === '') { // Keep the default value for empty nullables. continue; } $propertyName = $property->getName(); - $propertyType = $matches['type']; if ($propertyType === 'bool') { $value = (bool) $value; } elseif ($propertyType === 'int') { diff --git a/src/helpers/ContentLoader.php b/src/helpers/ContentLoader.php index 1d6d3db83f..9a5ebe86cd 100644 --- a/src/helpers/ContentLoader.php +++ b/src/helpers/ContentLoader.php @@ -17,42 +17,20 @@ * @author Tobias Zeising */ class ContentLoader { - /** @var Configuration configuration */ - private $configuration; - - /** @var \daos\DatabaseInterface database for optimization */ - private $database; - - /** @var IconStore icon store */ - private $iconStore; - - /** @var Image image helper */ - private $imageHelper; - - /** @var \daos\Items database access for saving new item */ - private $itemsDao; - - /** @var Logger */ - private $logger; - - /** @var \daos\Sources database access for saving source’s last update */ - private $sourcesDao; - - /** @var SpoutLoader spout loader */ - private $spoutLoader; - - /** @var ThumbnailStore thumbnail store */ - private $thumbnailStore; - - /** @var WebClient thumbnail store */ - private $webClient; - public const ICON_FORMAT = Image::FORMAT_PNG; public const THUMBNAIL_FORMAT = Image::FORMAT_JPEG; - /** - * ctor - */ + private Configuration $configuration; + private \daos\DatabaseInterface $database; + private IconStore $iconStore; + private Image $imageHelper; + private \daos\Items $itemsDao; + private Logger $logger; + private \daos\Sources $sourcesDao; + private SpoutLoader $spoutLoader; + private ThumbnailStore $thumbnailStore; + private WebClient $webClient; + public function __construct(Configuration $configuration, \daos\DatabaseInterface $database, IconStore $iconStore, Image $imageHelper, \daos\Items $itemsDao, Logger $logger, \daos\Sources $sourcesDao, SpoutLoader $spoutLoader, ThumbnailStore $thumbnailStore, WebClient $webClient) { $this->configuration = $configuration; $this->database = $database; @@ -450,16 +428,16 @@ public function cleanup(): void { // delete orphaned thumbnails $this->logger->debug('delete orphaned thumbnails'); - $this->thumbnailStore->cleanup(function($file) { - return $this->itemsDao->hasThumbnail($file); - }); + $this->thumbnailStore->cleanup( + fn($file) => $this->itemsDao->hasThumbnail($file) + ); $this->logger->debug('delete orphaned thumbnails finished'); // delete orphaned icons $this->logger->debug('delete orphaned icons'); - $this->iconStore->cleanup(function($file) { - return $this->itemsDao->hasIcon($file); - }); + $this->iconStore->cleanup( + fn($file) => $this->itemsDao->hasIcon($file) + ); $this->logger->debug('delete orphaned icons finished'); // optimize database diff --git a/src/helpers/DatabaseConnection.php b/src/helpers/DatabaseConnection.php index 1511a8ab97..f2029e2645 100644 --- a/src/helpers/DatabaseConnection.php +++ b/src/helpers/DatabaseConnection.php @@ -15,17 +15,13 @@ * Copyright (c) 2009-2019 F3::Factory/Bong Cosca */ class DatabaseConnection { - /** @var PDO Original PDO connection */ - private $pdo; + /** Whether a transaction is currently in progress */ + private bool $isInTransaction = false; - /** @var string */ - private $tableNamePrefix; + private PDO $pdo; - /** @var bool whether a transaction is currently in progress */ - private $isInTransaction = false; - - /** @var Logger */ - private $logger; + private Logger $logger; + private string $tableNamePrefix; /** * Instantiate class diff --git a/src/helpers/FeedReader.php b/src/helpers/FeedReader.php index 88319fcc93..6c4a57ffce 100644 --- a/src/helpers/FeedReader.php +++ b/src/helpers/FeedReader.php @@ -11,8 +11,7 @@ * Helper class for obtaining feeds */ class FeedReader { - /** @var SimplePie */ - private $simplepie; + private SimplePie $simplepie; public function __construct( SimplePie $simplepie, diff --git a/src/helpers/Filters/DisjunctionFilter.php b/src/helpers/Filters/DisjunctionFilter.php index 0f7cad1964..2023416f5f 100644 --- a/src/helpers/Filters/DisjunctionFilter.php +++ b/src/helpers/Filters/DisjunctionFilter.php @@ -11,11 +11,12 @@ * Filter that admits a list of items iff the inner filter admits any of them. * * @template T + * * @implements Filter> */ final class DisjunctionFilter implements Filter { /** @var Filter */ - private $filter; + private Filter $filter; /** * @param Filter $filter diff --git a/src/helpers/Filters/MapFilter.php b/src/helpers/Filters/MapFilter.php index d7b0468887..e0a8125ff9 100644 --- a/src/helpers/Filters/MapFilter.php +++ b/src/helpers/Filters/MapFilter.php @@ -14,11 +14,12 @@ * * @template T * @template InnerT + * * @implements Filter */ final class MapFilter implements Filter { /** @var Filter */ - private $filter; + private Filter $filter; /** @var callable(T): InnerT */ private $transform; diff --git a/src/helpers/Filters/NegationFilter.php b/src/helpers/Filters/NegationFilter.php index 9434fb8bbd..4a22246fe8 100644 --- a/src/helpers/Filters/NegationFilter.php +++ b/src/helpers/Filters/NegationFilter.php @@ -13,11 +13,12 @@ * Filter that rejects an item iff inner filter admits it. * * @template T + * * @implements Filter */ final class NegationFilter implements Filter { /** @var Filter */ - private $filter; + private Filter $filter; /** * @param Filter $filter diff --git a/src/helpers/Filters/RegexFilter.php b/src/helpers/Filters/RegexFilter.php index 0a56befdce..82223f0803 100644 --- a/src/helpers/Filters/RegexFilter.php +++ b/src/helpers/Filters/RegexFilter.php @@ -15,8 +15,7 @@ * @implements Filter */ final class RegexFilter implements Filter { - /** @var string */ - private $regex; + private string $regex; public function __construct(string $regex) { if (@preg_match('/^\\/((?content = $content; diff --git a/src/helpers/IconStore.php b/src/helpers/IconStore.php index 784dd828cc..2f33954911 100644 --- a/src/helpers/IconStore.php +++ b/src/helpers/IconStore.php @@ -11,11 +11,8 @@ * Icon storage. */ class IconStore { - /** @var Logger */ - private $logger; - - /** @var FileStorage */ - private $storage; + private FileStorage $storage; + private Logger $logger; public function __construct(FileStorage $storage, Logger $logger) { $this->storage = $storage; diff --git a/src/helpers/Image.php b/src/helpers/Image.php index 63eaa97545..d37c99ac01 100644 --- a/src/helpers/Image.php +++ b/src/helpers/Image.php @@ -45,11 +45,8 @@ class Image { 'application/ico' => 'ico', ]; - /** @var Logger */ - private $logger; - - /** @var WebClient */ - private $webClient; + private Logger $logger; + private WebClient $webClient; public function __construct(Logger $logger, WebClient $webClient) { $this->logger = $logger; diff --git a/src/helpers/ImageHolder.php b/src/helpers/ImageHolder.php index c1cafee884..9b499cf6b6 100644 --- a/src/helpers/ImageHolder.php +++ b/src/helpers/ImageHolder.php @@ -8,14 +8,11 @@ * Class holding image data and accompanying metadata. */ class ImageHolder { - /** @var string */ - private $data; + private string $data; /** @var Image::FORMAT_JPEG|Image::FORMAT_PNG */ - private $format; - /** @var int */ - private $width; - /** @var int */ - private $height; + private string $format; + private int $width; + private int $height; /** * @param Image::FORMAT_JPEG|Image::FORMAT_PNG $format diff --git a/src/helpers/ImageUtils.php b/src/helpers/ImageUtils.php index 0861b4daa4..acef4a2819 100644 --- a/src/helpers/ImageUtils.php +++ b/src/helpers/ImageUtils.php @@ -85,22 +85,25 @@ public static function parseShortcutIcons(string $html): array { usort($icons, Misc::compareBy( // largest icons first - [function($val) { - return (int) $val['sizes']; - }, Misc::ORDER_DESC], + [ + fn($val) => (int) $val['sizes'], + Misc::ORDER_DESC, + ], // then by rel priority - [function($val) { - return self::ICON_REL_WEIGHTS[$val['rel']]; - }, Misc::ORDER_DESC], + [ + fn($val) => self::ICON_REL_WEIGHTS[$val['rel']], + Misc::ORDER_DESC, + ], // and finally by order to make the sorting stable 'order' )); - return array_map(function($i) { - return $i['url']; - }, $icons); + return array_map( + fn($i) => $i['url'], + $icons + ); } /** diff --git a/src/helpers/Search.php b/src/helpers/Search.php index 5de07953b2..7ae96d5c68 100644 --- a/src/helpers/Search.php +++ b/src/helpers/Search.php @@ -26,8 +26,9 @@ public static function splitTerms(string $search): array { /** @var string[] */ // For PHPStan: The only case where null appears is array{null} when the $string is empty. $parts = str_getcsv(trim($search), ' '); - return array_filter($parts, function(string $item): bool { - return $item !== ''; - }); + return array_filter( + $parts, + fn(string $item): bool => $item !== '' + ); } } diff --git a/src/helpers/Session.php b/src/helpers/Session.php index de71cdf13d..ce56ba93d3 100644 --- a/src/helpers/Session.php +++ b/src/helpers/Session.php @@ -18,14 +18,10 @@ * Helper class for session management. */ class Session { - /** @var Logger */ - private $logger; + private bool $started = false; - /** @var View view */ - private $view; - - /** @var bool */ - private $started = false; + private Logger $logger; + private View $view; public function __construct(Logger $logger, View $view) { $this->logger = $logger; diff --git a/src/helpers/SimplePieFileGuzzle.php b/src/helpers/SimplePieFileGuzzle.php index ffb7840e03..59a04516c2 100644 --- a/src/helpers/SimplePieFileGuzzle.php +++ b/src/helpers/SimplePieFileGuzzle.php @@ -11,8 +11,7 @@ * Bridge to make SimplePie fetch resources using Guzzle library */ class SimplePieFileGuzzle extends File { - /** @var WebClient */ - private $webClient; + private WebClient $webClient; /** * @param string $url diff --git a/src/helpers/SpoutLoader.php b/src/helpers/SpoutLoader.php index 54ed25c0c5..59c0a7ae27 100644 --- a/src/helpers/SpoutLoader.php +++ b/src/helpers/SpoutLoader.php @@ -17,10 +17,9 @@ */ class SpoutLoader { /** @var ?array>, spout> array of available spouts */ - private $spouts = null; + private ?array $spouts = null; - /** @var Dice dependency injection container */ - private $dic; + private Dice $dic; public function __construct(Dice $dice) { $this->dic = $dice; diff --git a/src/helpers/Storage/FileStorage.php b/src/helpers/Storage/FileStorage.php index fe98c99472..207e47527c 100644 --- a/src/helpers/Storage/FileStorage.php +++ b/src/helpers/Storage/FileStorage.php @@ -10,11 +10,10 @@ * Simple file storage. */ class FileStorage { - /** @var Logger */ - private $logger; + private Logger $logger; - /** @var string Directory where the files will be stored */ - private $directory; + /** Directory where the files will be stored */ + private string $directory; public function __construct(Logger $logger, string $directory) { $this->logger = $logger; diff --git a/src/helpers/ThumbnailStore.php b/src/helpers/ThumbnailStore.php index e3ccd5abc8..09d2cacc15 100644 --- a/src/helpers/ThumbnailStore.php +++ b/src/helpers/ThumbnailStore.php @@ -11,11 +11,8 @@ * Thumbnail storage. */ class ThumbnailStore { - /** @var Logger */ - private $logger; - - /** @var FileStorage */ - private $storage; + private Logger $logger; + private FileStorage $storage; public function __construct(Logger $logger, FileStorage $storage) { $this->storage = $storage; diff --git a/src/helpers/View.php b/src/helpers/View.php index a598b3a048..9ec44705c2 100644 --- a/src/helpers/View.php +++ b/src/helpers/View.php @@ -20,11 +20,10 @@ * @author Tobias Zeising */ class View { - /** @var string current base url */ - public $base = ''; + /** Current base url */ + public string $base = ''; - /** @var Configuration configuration */ - private $configuration; + private Configuration $configuration; /** * set global view vars @@ -71,7 +70,7 @@ public function getBaseUrl(): string { ($protocol === 'https' && $_SERVER['SERVER_PORT'] != '443'))) { $port = ':' . $_SERVER['SERVER_PORT']; } - //Override the port if nginx is the front end and the traffic is being forwarded + // Override the port if nginx is the front end and the traffic is being forwarded if (isset($_SERVER['HTTP_X_FORWARDED_PORT'])) { $port = ':' . $_SERVER['HTTP_X_FORWARDED_PORT']; } diff --git a/src/helpers/ViewHelper.php b/src/helpers/ViewHelper.php index 290b1207b6..f4cf6c2a5e 100644 --- a/src/helpers/ViewHelper.php +++ b/src/helpers/ViewHelper.php @@ -14,8 +14,7 @@ * @author Tobias Zeising */ class ViewHelper { - /** @var Configuration configuration */ - private $configuration; + private Configuration $configuration; public function __construct(Configuration $configuration) { $this->configuration = $configuration; @@ -109,9 +108,11 @@ public function camoflauge(string $content): string { $camo = new \WillWashburn\Phpamo\Phpamo($this->configuration->camoKey, $this->configuration->camoDomain); - $content = preg_replace_callback("//i", function(array $matches) use ($camo) { - return ''; - }, $content); + $content = preg_replace_callback( + "//i", + fn(array $matches) => '', + $content + ); assert($content !== null, 'Regex must be valid'); diff --git a/src/helpers/WebClient.php b/src/helpers/WebClient.php index 2d1d162c7a..c034b01696 100644 --- a/src/helpers/WebClient.php +++ b/src/helpers/WebClient.php @@ -19,14 +19,9 @@ * @author Alexandre Rossi */ class WebClient { - /** @var Configuration configuration */ - private $configuration; - - /** @var ?GuzzleHttp\Client */ - private $httpClient = null; - - /** @var Logger */ - private $logger; + private Configuration $configuration; + private ?GuzzleHttp\Client $httpClient = null; + private Logger $logger; public function __construct(Configuration $configuration, Logger $logger) { $this->configuration = $configuration; diff --git a/src/spouts/Item.php b/src/spouts/Item.php index a488a2320f..e997ae9059 100644 --- a/src/spouts/Item.php +++ b/src/spouts/Item.php @@ -14,28 +14,23 @@ */ class Item { /** @var string an unique id for this item */ - private $id; + private string $id; - /** @var HtmlString title */ - private $title; + private HtmlString $title; /** @var HtmlString|(callable(static): HtmlString) content */ private $content; - /** @var ?string thumbnail */ - private $thumbnail; + private ?string $thumbnail = null; /** @var (?string)|(callable(static): ?string) icon */ private $icon; - /** @var string link */ - private $link; + private string $link; - /** @var ?DateTimeInterface date */ - private $date; + private ?DateTimeInterface $date = null; - /** @var ?string author */ - private $author; + private ?string $author = null; /** @var Extra extra data */ private $extraData; diff --git a/src/spouts/deviantart/dailydeviations.php b/src/spouts/deviantart/dailydeviations.php index 7cd044f431..9866f67bd2 100644 --- a/src/spouts/deviantart/dailydeviations.php +++ b/src/spouts/deviantart/dailydeviations.php @@ -12,14 +12,11 @@ * @author Tobias Zeising */ class dailydeviations extends \spouts\rss\images { - /** @var string name of source */ - public $name = 'DeviantArt: daily deviations'; + public string $name = 'DeviantArt: daily deviations'; - /** @var string description of this source type */ - public $description = 'Get daily deviations on DeviantArt.'; + public string $description = 'Get daily deviations on DeviantArt.'; - /** @var SpoutParameters configurable parameters */ - public $params = []; + public array $params = []; public function load(array $params): void { parent::load(['url' => $this->getXmlUrl($params)]); diff --git a/src/spouts/deviantart/user.php b/src/spouts/deviantart/user.php index 78d98b1011..e4cfd29416 100644 --- a/src/spouts/deviantart/user.php +++ b/src/spouts/deviantart/user.php @@ -14,14 +14,11 @@ * @author Tobias Zeising */ class user extends \spouts\rss\images { - /** @var string name of source */ - public $name = 'DeviantArt: user deviations'; + public string $name = 'DeviantArt: user deviations'; - /** @var string description of this source type */ - public $description = 'Get deviations of a DeviantArt user.'; + public string $description = 'Get deviations of a DeviantArt user.'; - /** @var SpoutParameters configurable parameters */ - public $params = [ + public array $params = [ 'username' => [ 'title' => 'Username', 'type' => Parameter::TYPE_TEXT, diff --git a/src/spouts/deviantart/usersfavs.php b/src/spouts/deviantart/usersfavs.php index 30b7121a61..04e71767c4 100644 --- a/src/spouts/deviantart/usersfavs.php +++ b/src/spouts/deviantart/usersfavs.php @@ -14,14 +14,11 @@ * @author Tobias Zeising */ class usersfavs extends \spouts\rss\images { - /** @var string name of source */ - public $name = 'DeviantArt: user favs'; + public string $name = 'DeviantArt: user favs'; - /** @var string description of this source type */ - public $description = 'Get favorites of a DeviantArt user.'; + public string $description = 'Get favorites of a DeviantArt user.'; - /** @var SpoutParameters configurable parameters */ - public $params = [ + public array $params = [ 'username' => [ 'title' => 'Username', 'type' => Parameter::TYPE_TEXT, diff --git a/src/spouts/facebook/page.php b/src/spouts/facebook/page.php index cfb4c85bb4..0a35f1284d 100644 --- a/src/spouts/facebook/page.php +++ b/src/spouts/facebook/page.php @@ -23,17 +23,15 @@ * @phpstan-type FbAttachment array{type: string, target: array{url: string}, media: array{image: array{src: string}}, description: string} * @phpstan-type FbItem array{id: string, message: string, permalink_url: string, created_time: string, attachments?: array{data: array}} * @phpstan-type FbParams array{user: string, app_id: string, app_secret: string} + * * @extends \spouts\spout */ class page extends \spouts\spout { - /** @var string name of source */ - public $name = 'Facebook: page feed'; + public string $name = 'Facebook: page feed'; - /** @var string description of this source type */ - public $description = 'Get posts from given Facebook page wall.'; + public string $description = 'Get posts from given Facebook page wall.'; - /** @var SpoutParameters configurable parameters */ - public $params = [ + public array $params = [ 'user' => [ 'title' => 'Page name', 'type' => Parameter::TYPE_TEXT, @@ -57,20 +55,17 @@ class page extends \spouts\spout { ], ]; - /** @var ?string title of the source */ - protected $title = null; - - /** @var ?string page picture */ - private $pageLink; + /** Title of the source */ + protected ?string $title = null; - /** @var ?string page picture */ - private $pagePicture; + private ?string $pageLink = null; - /** @var WebClient */ - private $webClient; + private ?string $pagePicture = null; /** @var FbItem[] current fetched items */ - private $items = []; + private array $items = []; + + private WebClient $webClient; public function __construct(WebClient $webClient) { $this->webClient = $webClient; @@ -114,7 +109,7 @@ public function getIcon(): ?string { public function getItems(): iterable { foreach ($this->items as $item) { $id = $item['id']; - $title = HtmlString::fromPlainText((mb_strlen($item['message']) > 80 ? mb_substr($item['message'], 0, 100) . '…' : $item['message'])); + $title = HtmlString::fromPlainText(mb_strlen($item['message']) > 80 ? mb_substr($item['message'], 0, 100) . '…' : $item['message']); $content = $this->getPostContent($item); $thumbnail = null; $icon = null; diff --git a/src/spouts/github/commits.php b/src/spouts/github/commits.php index c3ea8de88d..1f2f69b3f2 100644 --- a/src/spouts/github/commits.php +++ b/src/spouts/github/commits.php @@ -19,17 +19,15 @@ * * @phpstan-type Commit array{commit: array{message: string, author: array{date: string, name: string}}, sha: string, html_url: string} * @phpstan-type GhParams array{owner: string, repo: string, branch: string} + * * @extends \spouts\spout */ class commits extends \spouts\spout { - /** @var string name of source */ - public $name = 'GitHub: commits'; + public string $name = 'GitHub: commits'; - /** @var string description of this source type */ - public $description = 'List commits on a repository.'; + public string $description = 'List commits on a repository.'; - /** @var SpoutParameters configurable parameters */ - public $params = [ + public array $params = [ 'owner' => [ 'title' => 'Owner', 'type' => Parameter::TYPE_TEXT, @@ -53,20 +51,19 @@ class commits extends \spouts\spout { ], ]; - /** @var ?string title of the source */ - protected $title = null; - - /** @var string global html url for the source */ - protected $htmlUrl = ''; + /** Title of the source */ + protected ?string $title = null; - /** @var string URL of the favicon */ - protected $faviconUrl = 'https://assets-cdn.github.com/favicon.ico'; + /** Global html url for the source */ + protected string $htmlUrl = ''; - /** @var WebClient */ - private $webClient; + /** URL of the favicon */ + protected string $faviconUrl = 'https://assets-cdn.github.com/favicon.ico'; /** @var Commit[] current fetched items */ - private $items = []; + private array $items = []; + + private WebClient $webClient; public function __construct(WebClient $webClient) { $this->webClient = $webClient; diff --git a/src/spouts/reddit/reddit2.php b/src/spouts/reddit/reddit2.php index 2df3385174..420a1c13e3 100644 --- a/src/spouts/reddit/reddit2.php +++ b/src/spouts/reddit/reddit2.php @@ -24,17 +24,15 @@ * * @phpstan-type RedditItem array{data: array{id: string, url: string, title: string, permalink: string, selftext_html: string, created_utc: int, preview?: array{images?: array}, thumbnail: string}} * @phpstan-type RedditParams array{url: string, username?: string, password?: string} + * * @extends \spouts\spout */ class reddit2 extends \spouts\spout { - /** @var string name of spout */ - public $name = 'Reddit'; + public string $name = 'Reddit'; - /** @var string description of this source type */ - public $description = 'Get your fix from Reddit.'; + public string $description = 'Get your fix from Reddit.'; - /** @var SpoutParameters configurable parameters */ - public $params = [ + public array $params = [ 'url' => [ 'title' => 'Subreddit or multireddit url', 'type' => Parameter::TYPE_TEXT, @@ -58,20 +56,17 @@ class reddit2 extends \spouts\spout { ], ]; - /** @var ?string URL of the source */ - protected $htmlUrl = null; - - /** @var string the reddit_session cookie */ - private $reddit_session = ''; + /** URL of the source */ + protected ?string $htmlUrl = null; - /** @var Image image helper */ - private $imageHelper; - - /** @var WebClient */ - private $webClient; + /** the reddit_session cookie */ + private string $reddit_session = ''; /** @var RedditItem[] current fetched items */ - private $items = []; + private array $items = []; + + private Image $imageHelper; + private WebClient $webClient; public function __construct(Image $imageHelper, WebClient $webClient) { $this->imageHelper = $imageHelper; @@ -138,9 +133,7 @@ public function getItems(): iterable { $title = HtmlString::fromPlainText($item['data']['title']); $content = $this->getContent($url, $item); $thumbnail = $this->getThumbnail($item); - $icon = function(Item $item) use ($url): ?string { - return $this->findSiteIcon($url); - }; + $icon = fn(Item $item): ?string => $this->findSiteIcon($url); $link = 'https://www.reddit.com' . $item['data']['permalink']; // UNIX timestamp // https://www.reddit.com/r/redditdev/comments/3qsv97/whats_the_time_unit_for_created_utc_and_what_time/ diff --git a/src/spouts/rss/enclosures.php b/src/spouts/rss/enclosures.php index 267826108d..172d45bf02 100644 --- a/src/spouts/rss/enclosures.php +++ b/src/spouts/rss/enclosures.php @@ -16,11 +16,9 @@ * @author Daniel Rudolf */ class enclosures extends feed { - /** @var string name of spout */ - public $name = 'RSS Feed (with enclosures)'; + public string $name = 'RSS Feed (with enclosures)'; - /** @var string description of this source type */ - public $description = 'Get posts from RSS feed, including media enclosures.'; + public string $description = 'Get posts from RSS feed, including media enclosures.'; /** * @return \Generator> list of items diff --git a/src/spouts/rss/feed.php b/src/spouts/rss/feed.php index 2fcb04fdde..e468fee0df 100644 --- a/src/spouts/rss/feed.php +++ b/src/spouts/rss/feed.php @@ -22,14 +22,11 @@ * @extends \spouts\spout */ class feed extends \spouts\spout { - /** @var string name of source */ - public $name = 'RSS Feed'; + public string $name = 'RSS Feed'; - /** @var string description of this source type */ - public $description = 'Get posts from plain RSS/Atom feed.'; + public string $description = 'Get posts from plain RSS/Atom feed.'; - /** @var SpoutParameters configurable parameters */ - public $params = [ + public array $params = [ 'url' => [ 'title' => 'URL', 'type' => Parameter::TYPE_URL, @@ -39,23 +36,18 @@ class feed extends \spouts\spout { ], ]; - /** @var ?string URL of the source */ - protected $htmlUrl = null; + /** URL of the source */ + protected ?string $htmlUrl = null; - /** @var Logger */ - private $logger; - - /** @var FeedReader */ - private $feed; - - /** @var Image image helper */ - private $imageHelper; - - /** @var ?string title of the source */ - protected $title = null; + /** Title of the source */ + protected ?string $title = null; /** @var SimplePie\Item[] current fetched items */ - private $items = []; + private array $items = []; + + private Logger $logger; + private FeedReader $feed; + private Image $imageHelper; public function __construct(FeedReader $feed, Image $imageHelper, Logger $logger) { $this->imageHelper = $imageHelper; diff --git a/src/spouts/rss/fulltextrss.php b/src/spouts/rss/fulltextrss.php index 60c87a1c76..a7708f0bf4 100644 --- a/src/spouts/rss/fulltextrss.php +++ b/src/spouts/rss/fulltextrss.php @@ -25,14 +25,11 @@ * @author Tobias Zeising */ class fulltextrss extends feed { - /** @var string name of spout */ - public $name = 'RSS Feed (with content extraction)'; + public string $name = 'RSS Feed (with content extraction)'; - /** @var string description of this source type */ - public $description = 'Use “Graby” library to get full content of feed posts instead of partial content provided by some websites.'; + public string $description = 'Use “Graby” library to get full content of feed posts instead of partial content provided by some websites.'; - /** @var SpoutParameters configurable parameters */ - public $params = [ + public array $params = [ 'url' => [ 'title' => 'URL', 'type' => Parameter::TYPE_URL, @@ -42,20 +39,13 @@ class fulltextrss extends feed { ], ]; - /** @var string tag for logger */ - private static $loggerTag = 'selfoss.graby'; + /** Tag for logger */ + private static string $loggerTag = 'selfoss.graby'; - /** @var Configuration configuration */ - private $configuration; - - /** @var ?Graby */ - private $graby = null; - - /** @var Logger */ - private $logger; - - /** @var WebClient */ - private $webClient; + private Configuration $configuration; + private ?Graby $graby = null; + private Logger $logger; + private WebClient $webClient; public function __construct(Configuration $configuration, FeedReader $feed, Image $imageHelper, Logger $logger, WebClient $webClient) { parent::__construct($feed, $imageHelper, $logger); @@ -71,9 +61,9 @@ public function __construct(Configuration $configuration, FeedReader $feed, Imag public function getItems(): iterable { foreach (parent::getItems() as $originalItem) { $url = (string) self::removeTrackersFromUrl(new Uri($originalItem->getLink())); - yield $originalItem->withLink($url)->withContent(function(Item $item) use ($originalItem): HtmlString { - return $this->getFullContent($item->getLink(), $originalItem); - }); + yield $originalItem->withLink($url)->withContent( + fn(Item $item): HtmlString => $this->getFullContent($item->getLink(), $originalItem) + ); } } @@ -121,9 +111,7 @@ private static function removeTrackersFromUrl(Uri $uri): Uri { // Remove utm_* parameters $clean_query = array_filter( $q_array, - function(string $param): bool { - return !str_starts_with($param, 'utm_'); - } + fn(string $param): bool => !str_starts_with($param, 'utm_') ); $uri = $uri->withQuery(implode('&', $clean_query)); } diff --git a/src/spouts/rss/golem.php b/src/spouts/rss/golem.php index 6fc513fb65..278a04afb8 100644 --- a/src/spouts/rss/golem.php +++ b/src/spouts/rss/golem.php @@ -14,14 +14,11 @@ * @author Tobias Zeising */ class golem extends fulltextrss { - /** @var string name of spout */ - public $name = '[German] golem.de'; + public string $name = '[German] golem.de'; - /** @var string description of this source type */ - public $description = 'Fetch the golem news with full content (not only the header as content).'; + public string $description = 'Fetch the golem news with full content (not only the header as content).'; - /** @var SpoutParameters configurable parameters */ - public $params = [ + public array $params = [ 'section' => [ 'title' => 'Section', 'type' => Parameter::TYPE_SELECT, diff --git a/src/spouts/rss/heise.php b/src/spouts/rss/heise.php index a146bfdde8..32d995f338 100644 --- a/src/spouts/rss/heise.php +++ b/src/spouts/rss/heise.php @@ -15,14 +15,11 @@ * @author Daniel Seither */ class heise extends fulltextrss { - /** @var string name of spout */ - public $name = '[German] heise.de'; + public string $name = '[German] heise.de'; - /** @var string description of this source type */ - public $description = 'Fetch the heise news with full content (not only the header as content).'; + public string $description = 'Fetch the heise news with full content (not only the header as content).'; - /** @var SpoutParameters configurable parameters */ - public $params = [ + public array $params = [ 'section' => [ 'title' => 'Section', 'type' => Parameter::TYPE_SELECT, diff --git a/src/spouts/rss/images.php b/src/spouts/rss/images.php index 6770ad45fb..12bfe75b46 100644 --- a/src/spouts/rss/images.php +++ b/src/spouts/rss/images.php @@ -15,11 +15,9 @@ * @author Tobias Zeising */ class images extends feed { - /** @var string name of spout */ - public $name = 'RSS Feed Images'; + public string $name = 'RSS Feed Images'; - /** @var string description of this source type */ - public $description = 'Fetch images from given rss feed.'; + public string $description = 'Fetch images from given rss feed.'; /** * @return \Generator> list of items diff --git a/src/spouts/rss/lightreading.php b/src/spouts/rss/lightreading.php index ea2b39412b..b5d8473674 100644 --- a/src/spouts/rss/lightreading.php +++ b/src/spouts/rss/lightreading.php @@ -14,14 +14,11 @@ * @author Daniel Seither */ class lightreading extends fulltextrss { - /** @var string name of spout */ - public $name = '[English] lightreading.com'; + public string $name = '[English] lightreading.com'; - /** @var string description of this source type */ - public $description = 'Fetch Lightreading news with full content (not only the header as content).'; + public string $description = 'Fetch Lightreading news with full content (not only the header as content).'; - /** @var SpoutParameters configurable parameters */ - public $params = []; + public array $params = []; /** * addresses of feeds for the sections diff --git a/src/spouts/rss/mmospy.php b/src/spouts/rss/mmospy.php index c1da2b5a54..6926b02b71 100644 --- a/src/spouts/rss/mmospy.php +++ b/src/spouts/rss/mmospy.php @@ -12,14 +12,11 @@ * @author Tobias Zeising */ class mmospy extends fulltextrss { - /** @var string name of spout */ - public $name = '[German] mmo-spy.de'; + public string $name = '[German] mmo-spy.de'; - /** @var string description of this source type */ - public $description = 'Fetch the mmospy news with full content (not only the header as content).'; + public string $description = 'Fetch the mmospy news with full content (not only the header as content).'; - /** @var SpoutParameters configurable parameters */ - public $params = []; + public array $params = []; /** * addresses of feeds for the sections diff --git a/src/spouts/rss/prolinux.php b/src/spouts/rss/prolinux.php index 0ef95b4cca..30b1ad2b0b 100644 --- a/src/spouts/rss/prolinux.php +++ b/src/spouts/rss/prolinux.php @@ -17,14 +17,11 @@ * @author Sebastian Gibb */ class prolinux extends fulltextrss { - /** @var string name of spout */ - public $name = '[German] pro-linux.de'; + public string $name = '[German] pro-linux.de'; - /** @var string description of this source type */ - public $description = 'Fetch the pro-linux news with full content (not only the header as content).'; + public string $description = 'Fetch the pro-linux news with full content (not only the header as content).'; - /** @var SpoutParameters configurable parameters */ - public $params = [ + public array $params = [ 'section' => [ 'title' => 'Section', 'type' => Parameter::TYPE_SELECT, diff --git a/src/spouts/rss/teltarif.php b/src/spouts/rss/teltarif.php index ccf5ceb717..701a5fff19 100644 --- a/src/spouts/rss/teltarif.php +++ b/src/spouts/rss/teltarif.php @@ -14,14 +14,11 @@ * @author Daniel Seither */ class teltarif extends fulltextrss { - /** @var string name of spout */ - public $name = '[German] teltarif.de'; + public string $name = '[German] teltarif.de'; - /** @var string description of this source type */ - public $description = 'Fetch Telarif news with full content (not only the header as content).'; + public string $description = 'Fetch Telarif news with full content (not only the header as content).'; - /** @var SpoutParameters configurable parameters */ - public $params = []; + public array $params = []; /** * addresses of feeds for the sections diff --git a/src/spouts/spout.php b/src/spouts/spout.php index 94a5844f59..dc5e7e2c9a 100644 --- a/src/spouts/spout.php +++ b/src/spouts/spout.php @@ -15,11 +15,11 @@ * @author Tobias Zeising */ abstract class spout { - /** @var string name of source */ - public $name = ''; + /** Name of source */ + public string $name = ''; - /** @var string description of this source type */ - public $description = ''; + /** Description of this source type */ + public string $description = ''; /** /* Configurable parameters @@ -57,7 +57,7 @@ abstract class spout { * * @var SpoutParameters */ - public $params = []; + public array $params = []; /** * loads content for given source diff --git a/src/spouts/tumblr/user.php b/src/spouts/tumblr/user.php index 6bfea278df..d22d6ec723 100644 --- a/src/spouts/tumblr/user.php +++ b/src/spouts/tumblr/user.php @@ -14,14 +14,11 @@ * @author Tobias Zeising */ class user extends \spouts\rss\images { - /** @var string name of source */ - public $name = 'tumblr: user posts'; + public string $name = 'tumblr: user posts'; - /** @var string description of this source type */ - public $description = 'Get posts of a tumblr user.'; + public string $description = 'Get posts of a tumblr user.'; - /** @var SpoutParameters configurable parameters */ - public $params = [ + public array $params = [ 'username' => [ 'title' => 'Username', 'type' => Parameter::TYPE_TEXT, diff --git a/src/spouts/twitter/Search.php b/src/spouts/twitter/Search.php index bc2a0d9184..692b96746d 100644 --- a/src/spouts/twitter/Search.php +++ b/src/spouts/twitter/Search.php @@ -17,14 +17,11 @@ * @extends \spouts\spout */ class Search extends \spouts\spout { - /** @var string name of source */ - public $name = 'Twitter: search'; + public string $name = 'Twitter: search'; - /** @var string description of this source type */ - public $description = 'Fetch the search results for given query.'; + public string $description = 'Fetch the search results for given query.'; - /** @var SpoutParameters configurable parameters */ - public $params = [ + public array $params = [ 'consumer_key' => [ 'title' => 'Consumer Key', 'type' => Parameter::TYPE_TEXT, @@ -62,17 +59,16 @@ class Search extends \spouts\spout { ], ]; - /** @var string URL of the source */ - private $htmlUrl = ''; + /** URL of the source */ + private string $htmlUrl = ''; - /** @var ?string title of the source */ - private $title = null; + /** Title of the source */ + private ?string $title = null; /** @var iterable> current fetched items */ - private $items = []; + private iterable $items = []; - /** @var TwitterV1ApiClientFactory */ - private $clientFactory; + private TwitterV1ApiClientFactory $clientFactory; public function __construct(TwitterV1ApiClientFactory $clientFactory) { $this->clientFactory = $clientFactory; diff --git a/src/spouts/twitter/TwitterV1ApiClient.php b/src/spouts/twitter/TwitterV1ApiClient.php index 15e39b9b3d..3e270cfea9 100644 --- a/src/spouts/twitter/TwitterV1ApiClient.php +++ b/src/spouts/twitter/TwitterV1ApiClient.php @@ -29,8 +29,7 @@ class TwitterV1ApiClient { 'media', ]; - /** @var GuzzleHttp\Client HTTP client configured with Twitter OAuth support */ - private $client; + private GuzzleHttp\Client $client; public function __construct(GuzzleHttp\Client $client) { $this->client = $client; @@ -75,9 +74,13 @@ public function fetchTimeline(string $endpoint, array $params = []): iterable { $body = json_decode((string) $e->getResponse()->getBody()); if (isset($body->errors)) { - $errors = implode("\n", array_map(function($error) { - return $error->message; - }, $body->errors)); + $errors = implode( + "\n", + array_map( + fn($error) => $error->message, + $body->errors + ) + ); throw new \Exception($errors, $e->getCode(), $e); } diff --git a/src/spouts/twitter/TwitterV1ApiClientFactory.php b/src/spouts/twitter/TwitterV1ApiClientFactory.php index 2795a05755..937d49a2a8 100644 --- a/src/spouts/twitter/TwitterV1ApiClientFactory.php +++ b/src/spouts/twitter/TwitterV1ApiClientFactory.php @@ -15,8 +15,7 @@ * Factory for TwitterV1ApiClient. */ class TwitterV1ApiClientFactory { - /** @var WebClient */ - private $webClient; + private WebClient $webClient; public function __construct(WebClient $webClient) { $this->webClient = $webClient; diff --git a/src/spouts/twitter/hometimeline.php b/src/spouts/twitter/hometimeline.php index d4b984bf8a..ceefa31928 100644 --- a/src/spouts/twitter/hometimeline.php +++ b/src/spouts/twitter/hometimeline.php @@ -19,14 +19,11 @@ * @extends \spouts\spout */ class hometimeline extends \spouts\spout { - /** @var string name of source */ - public $name = 'Twitter: your timeline'; + public string $name = 'Twitter: your timeline'; - /** @var string description of this source type */ - public $description = 'Fetch your twitter timeline.'; + public string $description = 'Fetch your twitter timeline.'; - /** @var SpoutParameters configurable parameters */ - public $params = [ + public array $params = [ 'consumer_key' => [ 'title' => 'Consumer Key', 'type' => Parameter::TYPE_TEXT, @@ -57,17 +54,16 @@ class hometimeline extends \spouts\spout { ], ]; - /** @var string URL of the source */ - private $htmlUrl = ''; + /** URL of the source */ + private string $htmlUrl = ''; - /** @var ?string title of the source */ - private $title = null; + /** Title of the source */ + private ?string $title = null; /** @var iterable> current fetched items */ - private $items = []; + private iterable $items = []; - /** @var TwitterV1ApiClientFactory */ - private $clientFactory; + private TwitterV1ApiClientFactory $clientFactory; public function __construct(TwitterV1ApiClientFactory $clientFactory) { $this->clientFactory = $clientFactory; diff --git a/src/spouts/twitter/listtimeline.php b/src/spouts/twitter/listtimeline.php index 5dfc23cc32..cabcad038c 100644 --- a/src/spouts/twitter/listtimeline.php +++ b/src/spouts/twitter/listtimeline.php @@ -19,11 +19,10 @@ * @extends \spouts\spout */ class listtimeline extends \spouts\spout { - public $name = 'Twitter: list timeline'; - public $description = 'Fetch the timeline of a given list.'; + public string $name = 'Twitter: list timeline'; + public string $description = 'Fetch the timeline of a given list.'; - /** @var SpoutParameters configurable parameters */ - public $params = [ + public array $params = [ 'consumer_key' => [ 'title' => 'Consumer Key', 'type' => Parameter::TYPE_TEXT, @@ -68,17 +67,16 @@ class listtimeline extends \spouts\spout { ], ]; - /** @var string URL of the source */ - private $htmlUrl = ''; + /** URL of the source */ + private string $htmlUrl = ''; - /** @var ?string title of the source */ - private $title = null; + /** Title of the source */ + private ?string $title = null; /** @var iterable> current fetched items */ - private $items = []; + private iterable $items = []; - /** @var TwitterV1ApiClientFactory */ - private $clientFactory; + private TwitterV1ApiClientFactory $clientFactory; public function __construct(TwitterV1ApiClientFactory $clientFactory) { $this->clientFactory = $clientFactory; diff --git a/src/spouts/twitter/usertimeline.php b/src/spouts/twitter/usertimeline.php index bcabf28e33..e548c97c34 100644 --- a/src/spouts/twitter/usertimeline.php +++ b/src/spouts/twitter/usertimeline.php @@ -20,14 +20,11 @@ * @extends \spouts\spout */ class usertimeline extends \spouts\spout { - /** @var string name of source */ - public $name = 'Twitter: user timeline'; + public string $name = 'Twitter: user timeline'; - /** @var string description of this source type */ - public $description = 'Fetch the timeline of a given user.'; + public string $description = 'Fetch the timeline of a given user.'; - /** @var SpoutParameters configurable parameters */ - public $params = [ + public array $params = [ 'consumer_key' => [ 'title' => 'Consumer Key', 'type' => Parameter::TYPE_TEXT, @@ -65,17 +62,16 @@ class usertimeline extends \spouts\spout { ], ]; - /** @var string URL of the source */ - private $htmlUrl = ''; + /** URL of the source */ + private string $htmlUrl = ''; - /** @var ?string title of the source */ - private $title = null; + /** Title of the source */ + private ?string $title = null; /** @var iterable> current fetched items */ - private $items = []; + private iterable $items = []; - /** @var TwitterV1ApiClientFactory */ - private $clientFactory; + private TwitterV1ApiClientFactory $clientFactory; public function __construct(TwitterV1ApiClientFactory $clientFactory) { $this->clientFactory = $clientFactory; diff --git a/src/spouts/youtube/youtube.php b/src/spouts/youtube/youtube.php index 7da8cf6976..6c629a6e70 100644 --- a/src/spouts/youtube/youtube.php +++ b/src/spouts/youtube/youtube.php @@ -19,17 +19,15 @@ * @copyright Copyright (c) Tobias Zeising (http://www.aditu.de) * @license GPLv3 (https://www.gnu.org/licenses/gpl-3.0.html) * @author Tobias Zeising + * * @copywork Arndt Staudinger April 2013 */ class youtube extends \spouts\rss\feed { - /** @var string name of source */ - public $name = 'YouTube'; + public string $name = 'YouTube'; - /** @var string description of this source type */ - public $description = 'Follow videos from a YouTube channel or a playlist.'; + public string $description = 'Follow videos from a YouTube channel or a playlist.'; - /** @var SpoutParameters configurable parameters */ - public $params = [ + public array $params = [ 'channel' => [ 'title' => 'URL or username', 'type' => Parameter::TYPE_TEXT, @@ -39,8 +37,7 @@ class youtube extends \spouts\rss\feed { ], ]; - /** @var UrlHighlight urlHighlight */ - private $urlHighlight; + private UrlHighlight $urlHighlight; public function __construct(UrlHighlight $urlHighlight, FeedReader $feed, Image $imageHelper, Logger $logger) { parent::__construct($feed, $imageHelper, $logger); diff --git a/tests/Helpers/DetectSvgTest.php b/tests/Helpers/DetectSvgTest.php index be61820cf1..8cf80b4054 100644 --- a/tests/Helpers/DetectSvgTest.php +++ b/tests/Helpers/DetectSvgTest.php @@ -12,9 +12,9 @@ final class DetectSvgTest extends TestCase { * Detects a basic SVG file correctly. */ public function testBasic(): void { - $blob = << -EOD; + $blob = << + XML; $this->assertTrue( ImageUtils::detectSvg($blob) @@ -25,13 +25,13 @@ public function testBasic(): void { * Detects a SVG file with XML directives correctly. */ public function testDirectives(): void { - $blob = << - + $blob = << + - -EOD; + + XML; $this->assertTrue( ImageUtils::detectSvg($blob) @@ -42,10 +42,10 @@ public function testDirectives(): void { * Detects a SVG embedded in HTML file correctly. */ public function testInHtml(): void { - $blob = << - -EOD; + $blob = << + + HTML; $this->assertFalse( ImageUtils::detectSvg($blob) @@ -56,9 +56,9 @@ public function testInHtml(): void { * Detects a SVG embedded in HTML file with a doctype correctly. */ public function testInHtmlWithDoctype(): void { - $blob = <<Foo -EOD; + $blob = <<Foo + HTML; $this->assertFalse( ImageUtils::detectSvg($blob) @@ -69,9 +69,9 @@ public function testInHtmlWithDoctype(): void { * Detects a SVG embedded in HTML file with just a body correctly. */ public function testInHtmlWithBody(): void { - $blob = << -EOD; + $blob = << + HTML; $this->assertFalse( ImageUtils::detectSvg($blob) diff --git a/tests/Helpers/IconExtractorTest.php b/tests/Helpers/IconExtractorTest.php index 1229f7db65..5b40864393 100644 --- a/tests/Helpers/IconExtractorTest.php +++ b/tests/Helpers/IconExtractorTest.php @@ -12,15 +12,15 @@ final class IconExtractorTest extends TestCase { * Apple touch icons are supported. */ public function testAppleTouchIcon(): void { - $page = << - - - - - - -EOD; + $page = << + + + + + + + HTML; $this->assertEquals( [ @@ -34,15 +34,15 @@ public function testAppleTouchIcon(): void { * Apple touch precomposed icons are supported. */ public function testAppleTouchPrecomposedIcon(): void { - $page = << - - - - - - -EOD; + $page = << + + + + + + + HTML; $this->assertEquals( [ @@ -56,15 +56,15 @@ public function testAppleTouchPrecomposedIcon(): void { * Apple touch icons without sizes are supported. */ public function testAppleTouchWithoutSizesIcon(): void { - $page = << - - - - - - -EOD; + $page = << + + + + + + + HTML; $this->assertEquals( [ @@ -78,15 +78,15 @@ public function testAppleTouchWithoutSizesIcon(): void { * Shortcut icons are supported. */ public function testShortcutIcon(): void { - $page = << - - - - - - -EOD; + $page = << + + + + + + + HTML; $this->assertEquals( [ @@ -100,15 +100,15 @@ public function testShortcutIcon(): void { * Icons are supported. */ public function testIcon(): void { - $page = << - - - - - - -EOD; + $page = << + + + + + + + HTML; $this->assertEquals( [ @@ -122,17 +122,17 @@ public function testIcon(): void { * Multiple icons are recognized. */ public function testMultipleIcons(): void { - $page = << - - - - - - - - -EOD; + $page = << + + + + + + + + + HTML; $this->assertEquals( [ @@ -148,16 +148,16 @@ public function testMultipleIcons(): void { * Apple icons are prioritized over shortcut icons. */ public function testAppleAndIcon(): void { - $page = << - - - - - - - -EOD; + $page = << + + + + + + + + HTML; $this->assertEquals( [ @@ -172,16 +172,16 @@ public function testAppleAndIcon(): void { * Larger icons are prioritized over smaller ones. */ public function testAppleAndPrecomposed(): void { - $page = << - - - - - - - -EOD; + $page = << + + + + + + + + HTML; $this->assertEquals( [ @@ -196,16 +196,16 @@ public function testAppleAndPrecomposed(): void { * Apple precomposed icons are prioritized over normal touch icons. */ public function testAppleAndPrecomposedWithoutSizes(): void { - $page = << - - - - - - - -EOD; + $page = << + + + + + + + + HTML; $this->assertEquals( [ @@ -220,9 +220,9 @@ public function testAppleAndPrecomposedWithoutSizes(): void { * Uglified websites with unquoted atttributes are handled correctly. */ public function testUnquotedAttributes(): void { - $page = << -EOD; + $page = << + HTML; $this->assertEquals( [ @@ -238,14 +238,14 @@ public function testUnquotedAttributes(): void { * Null is returned when no icon found. */ public function testMissingIcon(): void { - $page = << - - - - - -EOD; + $page = << + + + + + + HTML; $this->assertEquals( [], @@ -257,15 +257,15 @@ public function testMissingIcon(): void { * Commented out icons are ignored. */ public function testCommentIcon(): void { - $page = << - - - - - - -EOD; + $page = << + + + + + + + HTML; $this->assertEquals( [], @@ -277,17 +277,17 @@ public function testCommentIcon(): void { * Icons inside script elements are ignored. */ public function testScriptIcon(): void { - $page = << - - - - - - -EOD; + $page = << + + + + + + + HTML; $this->assertEquals( [], diff --git a/tests/Helpers/ImageLazifierTest.php b/tests/Helpers/ImageLazifierTest.php index 568fe90558..3e0615e047 100644 --- a/tests/Helpers/ImageLazifierTest.php +++ b/tests/Helpers/ImageLazifierTest.php @@ -12,12 +12,12 @@ final class ImageLazifierTest extends TestCase { * Check that src attribute is renamed, other attributes are preserved and a properly-sized placeholder is chosen. */ public function testBasic(): void { - $input = << -EOD; - $expected = << -EOD; + $input = << + HTML; + $expected = << + HTML; $this->assertEquals( $expected, @@ -29,12 +29,12 @@ public function testBasic(): void { * Check that width for the placeholder is calculated from height. */ public function testWidthMissing(): void { - $input = << -EOD; - $expected = << -EOD; + $input = << + HTML; + $expected = << + HTML; $this->assertEquals( $expected, @@ -46,12 +46,12 @@ public function testWidthMissing(): void { * Check that height for the placeholder is calculated from width. */ public function testHeightMissing(): void { - $input = << -EOD; - $expected = << -EOD; + $input = << + HTML; + $expected = << + HTML; $this->assertEquals( $expected, @@ -63,12 +63,12 @@ public function testHeightMissing(): void { * Check that placeholder dimensions are chosen even when the image does not specify any. */ public function testDimensionsMissing(): void { - $input = << -EOD; - $expected = << -EOD; + $input = << + HTML; + $expected = << + HTML; $this->assertEquals( $expected, diff --git a/tests/Spouts/YouTubeTest.php b/tests/Spouts/YouTubeTest.php index 18a71e44fd..ade7df7ccf 100644 --- a/tests/Spouts/YouTubeTest.php +++ b/tests/Spouts/YouTubeTest.php @@ -88,34 +88,35 @@ function(array $remoteFile): Response { * @return Generator */ public function dataProvider(): Generator { - $zoggContent = HtmlString::fromRaw(<< -
-Playlist with parts 1, 2 and 3: https://www.youtube.com/watch?v=_k3_B9Eq7eM&list=PLbqa_PZ3dNahC2jqyu5dxN6I_wqAP2mjc
-
-0:00 Introduction
-0:22 Intro video
-0:53 Curvature and Hyperburritos
-2:10 The Big Bang
-5:38 Dark Energy and Dark Matter
-7:51 The CMB
-10:18 Circles in the Sky
-11:43 Cosmic Crystallography
-12:38 Hot Spots in the CMB
-14:51 The Cosmic Drum
-16:09 Conclusion
-16:37 Ad: Smooth Space
-17:32 Alien Cosmology
-18:48 Thanks
-19:03 The End
-
-
-Links
-- Concept, artwork and text by Martin Kuppe
-- Title music by OcularNebula (https://www.newgrounds.com/audio/listen/381971)
-- Other music and sound effects from Artlist.io
-- An article which gives an excellent overview of what we know: https://www.mdpi.com/2218-1997/2/1/1 -HTML + $zoggContent = HtmlString::fromRaw( + << +
+ Playlist with parts 1, 2 and 3: https://www.youtube.com/watch?v=_k3_B9Eq7eM&list=PLbqa_PZ3dNahC2jqyu5dxN6I_wqAP2mjc
+
+ 0:00 Introduction
+ 0:22 Intro video
+ 0:53 Curvature and Hyperburritos
+ 2:10 The Big Bang
+ 5:38 Dark Energy and Dark Matter
+ 7:51 The CMB
+ 10:18 Circles in the Sky
+ 11:43 Cosmic Crystallography
+ 12:38 Hot Spots in the CMB
+ 14:51 The Cosmic Drum
+ 16:09 Conclusion
+ 16:37 Ad: Smooth Space
+ 17:32 Alien Cosmology
+ 18:48 Thanks
+ 19:03 The End
+
+
+ Links
+ - Concept, artwork and text by Martin Kuppe
+ - Title music by OcularNebula (https://www.newgrounds.com/audio/listen/381971)
+ - Other music and sound effects from Artlist.io
+ - An article which gives an excellent overview of what we know: https://www.mdpi.com/2218-1997/2/1/1 + HTML ); yield [ @@ -160,11 +161,12 @@ public function dataProvider(): Generator { ], 'feedTitle' => 'BeeKeeping', 'firstItemTitle' => HtmlString::fromPlainText('Year of BeeKeeping Episode 15, Finding Queen'), - 'firstItemContent' => HtmlString::fromRaw(<< -
-this video originally was over an hour and I cut out half so... I actually should do that more. -HTML + 'firstItemContent' => HtmlString::fromRaw( + << +
+ this video originally was over an hour and I cut out half so... I actually should do that more. + HTML ), ]; @@ -175,13 +177,14 @@ public function dataProvider(): Generator { ], 'feedTitle' => 'Breaking Taps', 'firstItemTitle' => HtmlString::fromPlainText('Slow Motion Tuning Fork'), - 'firstItemContent' => HtmlString::fromRaw(<< -
-Small clarification: the large fork has a 180hz tone when analyzed with a frequency detector (and held up to your ear), but also higher overtones which is mostly what's heard on the microphone. I should have mentioned the overtones but slipped my mind when filming. Sorry!
-
-#shorts -HTML + 'firstItemContent' => HtmlString::fromRaw( + << +
+ Small clarification: the large fork has a 180hz tone when analyzed with a frequency detector (and held up to your ear), but also higher overtones which is mostly what's heard on the microphone. I should have mentioned the overtones but slipped my mind when filming. Sorry!
+
+ #shorts + HTML ), ]; }