From 1d8c752dc00ebfa8c5cb226cfa6e9325f2c72502 Mon Sep 17 00:00:00 2001 From: dena Date: Tue, 19 May 2026 15:34:25 +0200 Subject: [PATCH 1/8] use k8s lib fork --- composer.json | 8 +- composer.lock | 247 +++++++++++++++++++++++++------------------------- 2 files changed, 131 insertions(+), 124 deletions(-) diff --git a/composer.json b/composer.json index 782234cb..b90226c6 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,12 @@ ], "license": "MIT", "type": "project", + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/deer-wmde/kubernetes-client" + } + ], "require": { "absszero/laravel-stackdriver-error-reporting": "^1.9", "firebase/php-jwt": "^7.0", @@ -23,7 +29,7 @@ "lcobucci/jwt": "^5.6", "league/flysystem-aws-s3-v3": "^3.22", "lkaemmerling/laravel-horizon-prometheus-exporter": "^1.7", - "maclof/kubernetes-client": "^0.31.0", + "maclof/kubernetes-client": "dev-master#1cdc35708c41d9eda9758b644950a0dceb541bb2", "mxl/laravel-job": "^1.5", "php-http/guzzle7-adapter": "^1.0", "predis/predis": "^3.4" diff --git a/composer.lock b/composer.lock index 3138c3fa..5822c314 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": "b53936f6dbe98d5646390f1d2e1fe647", + "content-hash": "2a0d296c012a10de33b6d6c244e9eb75", "packages": [ { "name": "absszero/laravel-stackdriver-error-reporting", @@ -2601,16 +2601,16 @@ }, { "name": "laravel/prompts", - "version": "v0.3.17", + "version": "v0.3.18", "source": { "type": "git", "url": "https://github.com/laravel/prompts.git", - "reference": "6a82ac19a28b916ae0885828795dbd4c59d9a818" + "reference": "a19af51bb144bf87f08397921fa619f85c7d4e72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/6a82ac19a28b916ae0885828795dbd4c59d9a818", - "reference": "6a82ac19a28b916ae0885828795dbd4c59d9a818", + "url": "https://api.github.com/repos/laravel/prompts/zipball/a19af51bb144bf87f08397921fa619f85c7d4e72", + "reference": "a19af51bb144bf87f08397921fa619f85c7d4e72", "shasum": "" }, "require": { @@ -2654,9 +2654,9 @@ "description": "Add beautiful and user-friendly forms to your command-line applications.", "support": { "issues": "https://github.com/laravel/prompts/issues", - "source": "https://github.com/laravel/prompts/tree/v0.3.17" + "source": "https://github.com/laravel/prompts/tree/v0.3.18" }, - "time": "2026-04-20T16:07:33+00:00" + "time": "2026-05-19T00:47:18+00:00" }, { "name": "laravel/sentinel", @@ -3869,24 +3869,24 @@ }, { "name": "maclof/kubernetes-client", - "version": "0.31.0", + "version": "dev-master", "source": { "type": "git", - "url": "https://github.com/maclof/kubernetes-client.git", - "reference": "3246638c8ce40ff187f8f1c2bf709e2fd4f0883f" + "url": "https://github.com/deer-wmde/kubernetes-client.git", + "reference": "1cdc35708c41d9eda9758b644950a0dceb541bb2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maclof/kubernetes-client/zipball/3246638c8ce40ff187f8f1c2bf709e2fd4f0883f", - "reference": "3246638c8ce40ff187f8f1c2bf709e2fd4f0883f", + "url": "https://api.github.com/repos/deer-wmde/kubernetes-client/zipball/1cdc35708c41d9eda9758b644950a0dceb541bb2", + "reference": "1cdc35708c41d9eda9758b644950a0dceb541bb2", "shasum": "" }, "require": { - "illuminate/support": "^5.0|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "illuminate/support": "^5.0|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0", "php": "^7.4|^8.0", "php-http/client-common": "^2.0", "php-http/discovery": "^1.0", - "ratchet/pawl": "^0.3", + "ratchet/pawl": "^0.4.3", "softcreatr/jsonpath": "^0.5 || ^0.7 || ^0.8", "symfony/yaml": "^4.0|^5.0|^6.0|^7.0" }, @@ -3897,13 +3897,19 @@ "php-http/socket-client": "^2.0", "phpunit/phpunit": "~7.0|~9.5" }, + "default-branch": true, "type": "library", "autoload": { "psr-4": { "Maclof\\Kubernetes\\": "src/" } }, - "notification-url": "https://packagist.org/downloads/", + "autoload-dev": { + "classmap": [ + "tests/TestCase.php", + "tests/helpers/HttpMethodsMockClient.php" + ] + }, "license": [ "MIT" ], @@ -3921,10 +3927,9 @@ "kubernetes" ], "support": { - "issues": "https://github.com/maclof/kubernetes-client/issues", - "source": "https://github.com/maclof/kubernetes-client/tree/0.31.0" + "source": "https://github.com/deer-wmde/kubernetes-client/tree/master" }, - "time": "2024-03-14T08:01:22+00:00" + "time": "2026-04-09T13:43:50+00:00" }, { "name": "monolog/monolog", @@ -6200,26 +6205,27 @@ }, { "name": "ratchet/pawl", - "version": "v0.3.5", + "version": "v0.4.3", "source": { "type": "git", "url": "https://github.com/ratchetphp/Pawl.git", - "reference": "89ec703c76dc893484a2a0ed44b48a37d445abd5" + "reference": "2c582373c78271de32cb04c755c4c0db7e09c9c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ratchetphp/Pawl/zipball/89ec703c76dc893484a2a0ed44b48a37d445abd5", - "reference": "89ec703c76dc893484a2a0ed44b48a37d445abd5", + "url": "https://api.github.com/repos/ratchetphp/Pawl/zipball/2c582373c78271de32cb04c755c4c0db7e09c9c0", + "reference": "2c582373c78271de32cb04c755c4c0db7e09c9c0", "shasum": "" }, "require": { "evenement/evenement": "^3.0 || ^2.0", - "php": ">=5.4", - "ratchet/rfc6455": "^0.3", - "react/socket": "^1.0 || ^0.8 || ^0.7" + "guzzlehttp/psr7": "^2.0", + "php": ">=7.4", + "ratchet/rfc6455": "^0.3.1 || ^0.4.0", + "react/socket": "^1.9" }, "require-dev": { - "phpunit/phpunit": "~4.8" + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8" }, "suggest": { "reactivex/rxphp": "~2.0" @@ -6247,30 +6253,32 @@ ], "support": { "issues": "https://github.com/ratchetphp/Pawl/issues", - "source": "https://github.com/ratchetphp/Pawl/tree/master" + "source": "https://github.com/ratchetphp/Pawl/tree/v0.4.3" }, - "time": "2020-07-17T15:32:47+00:00" + "time": "2025-03-19T16:47:38+00:00" }, { "name": "ratchet/rfc6455", - "version": "v0.3.1", + "version": "v0.4.0", "source": { "type": "git", "url": "https://github.com/ratchetphp/RFC6455.git", - "reference": "7c964514e93456a52a99a20fcfa0de242a43ccdb" + "reference": "859d95f85dda0912c6d5b936d036d044e3af47ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ratchetphp/RFC6455/zipball/7c964514e93456a52a99a20fcfa0de242a43ccdb", - "reference": "7c964514e93456a52a99a20fcfa0de242a43ccdb", + "url": "https://api.github.com/repos/ratchetphp/RFC6455/zipball/859d95f85dda0912c6d5b936d036d044e3af47ef", + "reference": "859d95f85dda0912c6d5b936d036d044e3af47ef", "shasum": "" }, "require": { - "guzzlehttp/psr7": "^2 || ^1.7", - "php": ">=5.4.2" + "php": ">=7.4", + "psr/http-factory-implementation": "^1.0", + "symfony/polyfill-php80": "^1.15" }, "require-dev": { - "phpunit/phpunit": "^5.7", + "guzzlehttp/psr7": "^2.7", + "phpunit/phpunit": "^9.5", "react/socket": "^1.3" }, "type": "library", @@ -6304,9 +6312,9 @@ "support": { "chat": "https://gitter.im/reactphp/reactphp", "issues": "https://github.com/ratchetphp/RFC6455/issues", - "source": "https://github.com/ratchetphp/RFC6455/tree/v0.3.1" + "source": "https://github.com/ratchetphp/RFC6455/tree/v0.4.0" }, - "time": "2021-12-09T23:20:49+00:00" + "time": "2025-02-24T01:18:22+00:00" }, { "name": "react/cache", @@ -6893,22 +6901,21 @@ }, { "name": "symfony/clock", - "version": "v7.4.8", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/clock.git", - "reference": "674fa3b98e21531dd040e613479f5f6fa8f32111" + "reference": "b55a638b189a6faa875e0ccdb00908fb87af95b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/674fa3b98e21531dd040e613479f5f6fa8f32111", - "reference": "674fa3b98e21531dd040e613479f5f6fa8f32111", + "url": "https://api.github.com/repos/symfony/clock/zipball/b55a638b189a6faa875e0ccdb00908fb87af95b3", + "reference": "b55a638b189a6faa875e0ccdb00908fb87af95b3", "shasum": "" }, "require": { - "php": ">=8.2", - "psr/clock": "^1.0", - "symfony/polyfill-php83": "^1.28" + "php": ">=8.4", + "psr/clock": "^1.0" }, "provide": { "psr/clock-implementation": "1.0" @@ -6947,7 +6954,7 @@ "time" ], "support": { - "source": "https://github.com/symfony/clock/tree/v7.4.8" + "source": "https://github.com/symfony/clock/tree/v8.0.8" }, "funding": [ { @@ -6967,7 +6974,7 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/console", @@ -7069,20 +7076,20 @@ }, { "name": "symfony/css-selector", - "version": "v7.4.9", + "version": "v8.0.9", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "b75663ed96cf4756e28e3105476f220f92886cc4" + "reference": "3665cfade90565430909b906394c73c8739e57d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/b75663ed96cf4756e28e3105476f220f92886cc4", - "reference": "b75663ed96cf4756e28e3105476f220f92886cc4", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/3665cfade90565430909b906394c73c8739e57d0", + "reference": "3665cfade90565430909b906394c73c8739e57d0", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.4" }, "type": "library", "autoload": { @@ -7114,7 +7121,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.4.9" + "source": "https://github.com/symfony/css-selector/tree/v8.0.9" }, "funding": [ { @@ -7134,7 +7141,7 @@ "type": "tidelift" } ], - "time": "2026-04-18T13:18:21+00:00" + "time": "2026-04-18T13:51:42+00:00" }, { "name": "symfony/deprecation-contracts", @@ -7291,24 +7298,24 @@ }, { "name": "symfony/event-dispatcher", - "version": "v7.4.9", + "version": "v8.0.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "e4a2e29753c7801f7a8340e066cfa788f3bc8101" + "reference": "0c3c1a17604c4dbbec4b93fe162c538482096e1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/e4a2e29753c7801f7a8340e066cfa788f3bc8101", - "reference": "e4a2e29753c7801f7a8340e066cfa788f3bc8101", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/0c3c1a17604c4dbbec4b93fe162c538482096e1f", + "reference": "0c3c1a17604c4dbbec4b93fe162c538482096e1f", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.4", "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<6.4", + "symfony/security-http": "<7.4", "symfony/service-contracts": "<2.5" }, "provide": { @@ -7317,14 +7324,14 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0|^8.0", - "symfony/dependency-injection": "^6.4|^7.0|^8.0", - "symfony/error-handler": "^6.4|^7.0|^8.0", - "symfony/expression-language": "^6.4|^7.0|^8.0", - "symfony/framework-bundle": "^6.4|^7.0|^8.0", - "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/config": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/error-handler": "^7.4|^8.0", + "symfony/expression-language": "^7.4|^8.0", + "symfony/framework-bundle": "^7.4|^8.0", + "symfony/http-foundation": "^7.4|^8.0", "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^6.4|^7.0|^8.0" + "symfony/stopwatch": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -7352,7 +7359,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/v7.4.9" + "source": "https://github.com/symfony/event-dispatcher/tree/v8.0.9" }, "funding": [ { @@ -7372,7 +7379,7 @@ "type": "tidelift" } ], - "time": "2026-04-18T13:18:21+00:00" + "time": "2026-04-18T13:51:42+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -7968,20 +7975,20 @@ }, { "name": "symfony/options-resolver", - "version": "v7.4.8", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "2888fcdc4dc2fd5f7c7397be78631e8af12e02b4" + "reference": "b48bce0a70b914f6953dafbd10474df232ed4de8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/2888fcdc4dc2fd5f7c7397be78631e8af12e02b4", - "reference": "2888fcdc4dc2fd5f7c7397be78631e8af12e02b4", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/b48bce0a70b914f6953dafbd10474df232ed4de8", + "reference": "b48bce0a70b914f6953dafbd10474df232ed4de8", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.4", "symfony/deprecation-contracts": "^2.5|^3" }, "type": "library", @@ -8015,7 +8022,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.4.8" + "source": "https://github.com/symfony/options-resolver/tree/v8.0.8" }, "funding": [ { @@ -8035,7 +8042,7 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/polyfill-ctype", @@ -9113,35 +9120,34 @@ }, { "name": "symfony/string", - "version": "v7.4.11", + "version": "v8.0.11", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "965f7306a43383d02c6aca1e3f3bd2f0ea5dee15" + "reference": "39be2ad058a3c0bd558edca23e65f009865d75ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/965f7306a43383d02c6aca1e3f3bd2f0ea5dee15", - "reference": "965f7306a43383d02c6aca1e3f3bd2f0ea5dee15", + "url": "https://api.github.com/repos/symfony/string/zipball/39be2ad058a3c0bd558edca23e65f009865d75ff", + "reference": "39be2ad058a3c0bd558edca23e65f009865d75ff", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.33", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" + "php": ">=8.4", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-intl-grapheme": "^1.33", + "symfony/polyfill-intl-normalizer": "^1.0", + "symfony/polyfill-mbstring": "^1.0" }, "conflict": { "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/emoji": "^7.1|^8.0", - "symfony/http-client": "^6.4|^7.0|^8.0", - "symfony/intl": "^6.4|^7.0|^8.0", + "symfony/emoji": "^7.4|^8.0", + "symfony/http-client": "^7.4|^8.0", + "symfony/intl": "^7.4|^8.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4|^7.0|^8.0" + "symfony/var-exporter": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -9180,7 +9186,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.4.11" + "source": "https://github.com/symfony/string/tree/v8.0.11" }, "funding": [ { @@ -9200,38 +9206,31 @@ "type": "tidelift" } ], - "time": "2026-05-13T12:04:42+00:00" + "time": "2026-05-13T12:07:53+00:00" }, { "name": "symfony/translation", - "version": "v7.4.10", + "version": "v8.0.10", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "ada7578c30dd5feaa8259cff3e885069ea81ddde" + "reference": "f63e9342e12646a57c91ef8a366a4f9d8e557b67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/ada7578c30dd5feaa8259cff3e885069ea81ddde", - "reference": "ada7578c30dd5feaa8259cff3e885069ea81ddde", + "url": "https://api.github.com/repos/symfony/translation/zipball/f63e9342e12646a57c91ef8a366a4f9d8e557b67", + "reference": "f63e9342e12646a57c91ef8a366a4f9d8e557b67", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/translation-contracts": "^2.5.3|^3.3" + "php": ">=8.4", + "symfony/polyfill-mbstring": "^1.0", + "symfony/translation-contracts": "^3.6.1" }, "conflict": { "nikic/php-parser": "<5.0", - "symfony/config": "<6.4", - "symfony/console": "<6.4", - "symfony/dependency-injection": "<6.4", "symfony/http-client-contracts": "<2.5", - "symfony/http-kernel": "<6.4", - "symfony/service-contracts": "<2.5", - "symfony/twig-bundle": "<6.4", - "symfony/yaml": "<6.4" + "symfony/service-contracts": "<2.5" }, "provide": { "symfony/translation-implementation": "2.3|3.0" @@ -9239,17 +9238,17 @@ "require-dev": { "nikic/php-parser": "^5.0", "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0|^8.0", - "symfony/console": "^6.4|^7.0|^8.0", - "symfony/dependency-injection": "^6.4|^7.0|^8.0", - "symfony/finder": "^6.4|^7.0|^8.0", + "symfony/config": "^7.4|^8.0", + "symfony/console": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/finder": "^7.4|^8.0", "symfony/http-client-contracts": "^2.5|^3.0", - "symfony/http-kernel": "^6.4|^7.0|^8.0", - "symfony/intl": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/intl": "^7.4|^8.0", "symfony/polyfill-intl-icu": "^1.21", - "symfony/routing": "^6.4|^7.0|^8.0", + "symfony/routing": "^7.4|^8.0", "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^6.4|^7.0|^8.0" + "symfony/yaml": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -9280,7 +9279,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.4.10" + "source": "https://github.com/symfony/translation/tree/v8.0.10" }, "funding": [ { @@ -9300,7 +9299,7 @@ "type": "tidelift" } ], - "time": "2026-05-06T11:19:24+00:00" + "time": "2026-05-06T11:30:54+00:00" }, { "name": "symfony/translation-contracts", @@ -9551,16 +9550,16 @@ }, { "name": "symfony/yaml", - "version": "v7.4.8", + "version": "v7.4.11", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "c58fdf7b3d6c2995368264c49e4e8b05bcff2883" + "reference": "e2eb64a57763815ccae07ac1c7653d6cc1c326fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/c58fdf7b3d6c2995368264c49e4e8b05bcff2883", - "reference": "c58fdf7b3d6c2995368264c49e4e8b05bcff2883", + "url": "https://api.github.com/repos/symfony/yaml/zipball/e2eb64a57763815ccae07ac1c7653d6cc1c326fd", + "reference": "e2eb64a57763815ccae07ac1c7653d6cc1c326fd", "shasum": "" }, "require": { @@ -9603,7 +9602,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.4.8" + "source": "https://github.com/symfony/yaml/tree/v7.4.11" }, "funding": [ { @@ -9623,7 +9622,7 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-05-13T12:04:42+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -12285,7 +12284,9 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": { + "maclof/kubernetes-client": 20 + }, "prefer-stable": true, "prefer-lowest": false, "platform": {}, From 97aea68f00d23df00eee41cbe54b5599609a52ca Mon Sep 17 00:00:00 2001 From: dena Date: Tue, 19 May 2026 15:35:18 +0200 Subject: [PATCH 2/8] upgrade to Laravel 12 --- composer.json | 2 +- composer.lock | 173 +++++++++++++++++++++++++++++++++++++------------- 2 files changed, 131 insertions(+), 44 deletions(-) diff --git a/composer.json b/composer.json index b90226c6..c5b82116 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "guzzlehttp/psr7": "^2.9", "hackzilla/password-generator": "^1.6", "intervention/image": "^2.5", - "laravel/framework": "^11.51", + "laravel/framework": "^12.0", "laravel/horizon": "^5.23", "laravel/passport": "^12.4", "laravel/tinker": "^3.0", diff --git a/composer.lock b/composer.lock index 5822c314..9c5d67b3 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": "2a0d296c012a10de33b6d6c244e9eb75", + "content-hash": "3094ee376eaa04ee8591a3676d254806", "packages": [ { "name": "absszero/laravel-stackdriver-error-reporting", @@ -2230,20 +2230,20 @@ }, { "name": "laravel/framework", - "version": "v11.52.0", + "version": "v12.59.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "98c1c33e00dd28f22a6527de98c021ab112a3ae6" + "reference": "70a838b1a6f12abaf5bebb76ea4f28fbd37451fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/98c1c33e00dd28f22a6527de98c021ab112a3ae6", - "reference": "98c1c33e00dd28f22a6527de98c021ab112a3ae6", + "url": "https://api.github.com/repos/laravel/framework/zipball/70a838b1a6f12abaf5bebb76ea4f28fbd37451fa", + "reference": "70a838b1a6f12abaf5bebb76ea4f28fbd37451fa", "shasum": "" }, "require": { - "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12|^0.13|^0.14", + "brick/math": "^0.11|^0.12|^0.13|^0.14", "composer-runtime-api": "^2.2", "doctrine/inflector": "^2.0.5", "dragonmantank/cron-expression": "^3.4", @@ -2258,32 +2258,34 @@ "fruitcake/php-cors": "^1.3", "guzzlehttp/guzzle": "^7.8.2", "guzzlehttp/uri-template": "^1.0", - "laravel/prompts": "^0.1.18|^0.2.0|^0.3.0", + "laravel/prompts": "^0.3.0", "laravel/serializable-closure": "^1.3|^2.0", - "league/commonmark": "^2.7", + "league/commonmark": "^2.8.1", "league/flysystem": "^3.25.1", "league/flysystem-local": "^3.25.1", "league/uri": "^7.5.1", "monolog/monolog": "^3.0", - "nesbot/carbon": "^2.72.6|^3.8.4", + "nesbot/carbon": "^3.8.4", "nunomaduro/termwind": "^2.0", "php": "^8.2", "psr/container": "^1.1.1|^2.0.1", "psr/log": "^1.0|^2.0|^3.0", "psr/simple-cache": "^1.0|^2.0|^3.0", "ramsey/uuid": "^4.7", - "symfony/console": "^7.0.3", - "symfony/error-handler": "^7.0.3", - "symfony/finder": "^7.0.3", + "symfony/console": "^7.2.0", + "symfony/error-handler": "^7.2.0", + "symfony/finder": "^7.2.0", "symfony/http-foundation": "^7.2.0", - "symfony/http-kernel": "^7.0.3", - "symfony/mailer": "^7.0.3", - "symfony/mime": "^7.0.3", - "symfony/polyfill-php83": "^1.31", - "symfony/process": "^7.0.3", - "symfony/routing": "^7.0.3", - "symfony/uid": "^7.0.3", - "symfony/var-dumper": "^7.0.3", + "symfony/http-kernel": "^7.2.0", + "symfony/mailer": "^7.2.0", + "symfony/mime": "^7.2.0", + "symfony/polyfill-php83": "^1.33", + "symfony/polyfill-php84": "^1.34", + "symfony/polyfill-php85": "^1.34", + "symfony/process": "^7.2.0", + "symfony/routing": "^7.2.0", + "symfony/uid": "^7.2.0", + "symfony/var-dumper": "^7.2.0", "tijsverkoyen/css-to-inline-styles": "^2.2.5", "vlucas/phpdotenv": "^5.6.1", "voku/portable-ascii": "^2.0.2" @@ -2315,6 +2317,7 @@ "illuminate/filesystem": "self.version", "illuminate/hashing": "self.version", "illuminate/http": "self.version", + "illuminate/json-schema": "self.version", "illuminate/log": "self.version", "illuminate/macroable": "self.version", "illuminate/mail": "self.version", @@ -2324,6 +2327,7 @@ "illuminate/process": "self.version", "illuminate/queue": "self.version", "illuminate/redis": "self.version", + "illuminate/reflection": "self.version", "illuminate/routing": "self.version", "illuminate/session": "self.version", "illuminate/support": "self.version", @@ -2347,17 +2351,18 @@ "league/flysystem-read-only": "^3.25.1", "league/flysystem-sftp-v3": "^3.25.1", "mockery/mockery": "^1.6.10", - "orchestra/testbench-core": "^9.18.0", - "pda/pheanstalk": "^5.0.6", + "opis/json-schema": "^2.4.1", + "orchestra/testbench-core": "^10.9.0", + "pda/pheanstalk": "^5.0.6|^7.0.0", "php-http/discovery": "^1.15", - "phpstan/phpstan": "2.1.41", - "phpunit/phpunit": "^10.5.35|^11.3.6|^12.0.1", - "predis/predis": "^2.3", - "resend/resend-php": "^0.10.0", - "symfony/cache": "^7.0.3", - "symfony/http-client": "^7.0.3", - "symfony/psr-http-message-bridge": "^7.0.3", - "symfony/translation": "^7.0.3" + "phpstan/phpstan": "^2.1.41", + "phpunit/phpunit": "^10.5.35|^11.5.3|^12.0.1", + "predis/predis": "^2.3|^3.0", + "resend/resend-php": "^0.10.0|^1.0", + "symfony/cache": "^7.2.0", + "symfony/http-client": "^7.2.0", + "symfony/psr-http-message-bridge": "^7.2.0", + "symfony/translation": "^7.2.0" }, "suggest": { "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", @@ -2372,7 +2377,7 @@ "ext-pdo": "Required to use all database features.", "ext-posix": "Required to use all features of the queue worker.", "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0|^6.0).", - "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", + "fakerphp/faker": "Required to generate fake data using the fake() helper (^1.23).", "filp/whoops": "Required for friendly error pages in development (^2.14.3).", "laravel/tinker": "Required to use the tinker console command (^2.0).", "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.25.1).", @@ -2383,22 +2388,22 @@ "mockery/mockery": "Required to use mocking (^1.6).", "pda/pheanstalk": "Required to use the beanstalk queue driver (^5.0).", "php-http/discovery": "Required to use PSR-7 bridging features (^1.15).", - "phpunit/phpunit": "Required to use assertions and run tests (^10.5.35|^11.3.6|^12.0.1).", - "predis/predis": "Required to use the predis connector (^2.3).", + "phpunit/phpunit": "Required to use assertions and run tests (^10.5.35|^11.5.3|^12.0.1).", + "predis/predis": "Required to use the predis connector (^2.3|^3.0).", "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", - "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0).", - "symfony/cache": "Required to PSR-6 cache bridge (^7.0).", - "symfony/filesystem": "Required to enable support for relative symbolic links (^7.0).", - "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.0).", - "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.0).", - "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.0).", - "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.0)." + "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0|^1.0).", + "symfony/cache": "Required to PSR-6 cache bridge (^7.2).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^7.2).", + "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.2).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.2).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.2).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.2)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "11.x-dev" + "dev-master": "12.x-dev" } }, "autoload": { @@ -2409,6 +2414,7 @@ "src/Illuminate/Filesystem/functions.php", "src/Illuminate/Foundation/helpers.php", "src/Illuminate/Log/functions.php", + "src/Illuminate/Reflection/helpers.php", "src/Illuminate/Support/functions.php", "src/Illuminate/Support/helpers.php" ], @@ -2417,7 +2423,8 @@ "Illuminate\\Support\\": [ "src/Illuminate/Macroable/", "src/Illuminate/Collections/", - "src/Illuminate/Conditionable/" + "src/Illuminate/Conditionable/", + "src/Illuminate/Reflection/" ] } }, @@ -2441,7 +2448,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2026-05-14T15:31:55+00:00" + "time": "2026-05-14T15:31:40+00:00" }, { "name": "laravel/horizon", @@ -8630,6 +8637,86 @@ ], "time": "2026-04-10T17:25:58+00:00" }, + { + "name": "symfony/polyfill-php84", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php84.git", + "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/88486db2c389b290bf87ff1de7ebc1e13e42bb06", + "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php84\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php84/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-10T18:47:49+00:00" + }, { "name": "symfony/polyfill-php85", "version": "v1.37.0", From 8550ca598522d5e8a9821be514db087058f3cb10 Mon Sep 17 00:00:00 2001 From: dena Date: Tue, 19 May 2026 16:02:08 +0200 Subject: [PATCH 3/8] use composer 2.9 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 5fb67fc9..ae8464f3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM composer:2.3 as composer +FROM composer:2.9 as composer COPY ./composer.json /tmp/src1/composer.json COPY ./composer.lock /tmp/src1/composer.lock From 7a7d13dac88ae9c54c86a76e75964a1c18c8e104 Mon Sep 17 00:00:00 2001 From: dena Date: Tue, 19 May 2026 16:02:47 +0200 Subject: [PATCH 4/8] remove unused and blocking php ext opencensus --- Dockerfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index ae8464f3..fa1e74b6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,9 +27,6 @@ RUN apt-get update \ && docker-php-ext-install pdo pdo_mysql \ # For rewrite rules && a2enmod rewrite \ - # Needed for gluedev/laravel-stackdriver - && pecl install opencensus-alpha \ - && docker-php-ext-enable opencensus \ && rm -rf /var/lib/apt/lists/* ENV APACHE_DOCUMENT_ROOT /var/www/html/public From 19a8cece3b1942447df6b64af90c15a2f75f7bae Mon Sep 17 00:00:00 2001 From: dena Date: Tue, 19 May 2026 16:03:22 +0200 Subject: [PATCH 5/8] use php 8.4 --- Dockerfile | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index fa1e74b6..560732d1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ WORKDIR /tmp/src2 RUN composer install --no-dev --no-progress --optimize-autoloader --ignore-platform-req=ext-pcntl -FROM php:8.2-apache +FROM php:8.4-apache RUN apt-get update \ # Needed for the imagick php extension install diff --git a/composer.json b/composer.json index c5b82116..0eb62d86 100644 --- a/composer.json +++ b/composer.json @@ -73,7 +73,7 @@ }, "config": { "platform": { - "php": "8.2" + "php": "8.4" }, "preferred-install": "dist", "sort-packages": true, From 85d66868a49386a99d852593e70cb25de55835b7 Mon Sep 17 00:00:00 2001 From: dena Date: Tue, 19 May 2026 16:03:56 +0200 Subject: [PATCH 6/8] run composer update --- composer.lock | 127 +++++++++++++++++++++++++------------------------- 1 file changed, 64 insertions(+), 63 deletions(-) diff --git a/composer.lock b/composer.lock index 9c5d67b3..e26768db 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": "3094ee376eaa04ee8591a3676d254806", + "content-hash": "1f5510b9f951faad871735e3d2dcbc1c", "packages": [ { "name": "absszero/laravel-stackdriver-error-reporting", @@ -119,16 +119,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.381.1", + "version": "3.381.3", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "405affc23ea14950c378d5ae79420302fcb467dc" + "reference": "989f4776aed2a3b184a5b64046542e8fe66e99e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/405affc23ea14950c378d5ae79420302fcb467dc", - "reference": "405affc23ea14950c378d5ae79420302fcb467dc", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/989f4776aed2a3b184a5b64046542e8fe66e99e2", + "reference": "989f4776aed2a3b184a5b64046542e8fe66e99e2", "shasum": "" }, "require": { @@ -210,9 +210,9 @@ "support": { "forum": "https://github.com/aws/aws-sdk-php/discussions", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.381.1" + "source": "https://github.com/aws/aws-sdk-php/tree/3.381.3" }, - "time": "2026-05-14T18:08:28+00:00" + "time": "2026-05-18T18:21:09+00:00" }, { "name": "brick/math", @@ -1095,16 +1095,16 @@ }, { "name": "google/cloud-core", - "version": "v1.72.0", + "version": "v1.72.1", "source": { "type": "git", "url": "https://github.com/googleapis/google-cloud-php-core.git", - "reference": "62cf5d2243af167c75019743c5aebcf25c3905ca" + "reference": "aa7869016cb9e87e95071bb92579fd22146ababb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-cloud-php-core/zipball/62cf5d2243af167c75019743c5aebcf25c3905ca", - "reference": "62cf5d2243af167c75019743c5aebcf25c3905ca", + "url": "https://api.github.com/repos/googleapis/google-cloud-php-core/zipball/aa7869016cb9e87e95071bb92579fd22146ababb", + "reference": "aa7869016cb9e87e95071bb92579fd22146ababb", "shasum": "" }, "require": { @@ -1156,9 +1156,9 @@ ], "description": "Google Cloud PHP shared dependency, providing functionality useful to all components.", "support": { - "source": "https://github.com/googleapis/google-cloud-php-core/tree/v1.72.0" + "source": "https://github.com/googleapis/google-cloud-php-core/tree/v1.72.1" }, - "time": "2026-04-09T21:01:46+00:00" + "time": "2026-05-12T19:06:48+00:00" }, { "name": "google/cloud-error-reporting", @@ -1341,16 +1341,16 @@ }, { "name": "google/gax", - "version": "v1.42.3", + "version": "v1.42.4", "source": { "type": "git", "url": "https://github.com/googleapis/gax-php.git", - "reference": "9dce5145169f2390ef2500d638c3cb5632054a96" + "reference": "9b1f5fb68960a9020e34fdb88583bcd43779e4fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/gax-php/zipball/9dce5145169f2390ef2500d638c3cb5632054a96", - "reference": "9dce5145169f2390ef2500d638c3cb5632054a96", + "url": "https://api.github.com/repos/googleapis/gax-php/zipball/9b1f5fb68960a9020e34fdb88583bcd43779e4fd", + "reference": "9b1f5fb68960a9020e34fdb88583bcd43779e4fd", "shasum": "" }, "require": { @@ -1392,9 +1392,9 @@ ], "support": { "issues": "https://github.com/googleapis/gax-php/issues", - "source": "https://github.com/googleapis/gax-php/tree/v1.42.3" + "source": "https://github.com/googleapis/gax-php/tree/v1.42.4" }, - "time": "2026-04-30T20:59:42+00:00" + "time": "2026-05-11T17:49:55+00:00" }, { "name": "google/grpc-gcp", @@ -1531,30 +1531,31 @@ }, { "name": "google/recaptcha", - "version": "1.3.0", + "version": "1.5", "source": { "type": "git", "url": "https://github.com/google/recaptcha.git", - "reference": "d59a801e98a4e9174814a6d71bbc268dff1202df" + "reference": "c57f0b96babc8c9fb64cb555cd7b2c5aadfbe58d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/google/recaptcha/zipball/d59a801e98a4e9174814a6d71bbc268dff1202df", - "reference": "d59a801e98a4e9174814a6d71bbc268dff1202df", + "url": "https://api.github.com/repos/google/recaptcha/zipball/c57f0b96babc8c9fb64cb555cd7b2c5aadfbe58d", + "reference": "c57f0b96babc8c9fb64cb555cd7b2c5aadfbe58d", "shasum": "" }, "require": { - "php": ">=8" + "php": ">=8.4" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.14", - "php-coveralls/php-coveralls": "^2.5", - "phpunit/phpunit": "^10" + "friendsofphp/php-cs-fixer": "^3.95", + "php-coveralls/php-coveralls": "^2.9.1", + "phpstan/phpstan": "^2.1.51", + "phpunit/phpunit": "^13.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-main": "1.4.x-dev" } }, "autoload": { @@ -1579,7 +1580,7 @@ "issues": "https://github.com/google/recaptcha/issues", "source": "https://github.com/google/recaptcha" }, - "time": "2023-02-18T17:41:46+00:00" + "time": "2026-04-27T09:26:38+00:00" }, { "name": "graham-campbell/result-type", @@ -2174,16 +2175,16 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "2.4-dev" - }, "laravel": { - "providers": [ - "Intervention\\Image\\ImageServiceProvider" - ], "aliases": { "Image": "Intervention\\Image\\Facades\\Image" - } + }, + "providers": [ + "Intervention\\Image\\ImageServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "2.4-dev" } }, "autoload": { @@ -2916,34 +2917,34 @@ }, { "name": "lcobucci/clock", - "version": "3.3.1", + "version": "3.6.0", "source": { "type": "git", "url": "https://github.com/lcobucci/clock.git", - "reference": "db3713a61addfffd615b79bf0bc22f0ccc61b86b" + "reference": "4cdd88f761e9be9095ccbedf3e08d61ae216c643" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lcobucci/clock/zipball/db3713a61addfffd615b79bf0bc22f0ccc61b86b", - "reference": "db3713a61addfffd615b79bf0bc22f0ccc61b86b", + "url": "https://api.github.com/repos/lcobucci/clock/zipball/4cdd88f761e9be9095ccbedf3e08d61ae216c643", + "reference": "4cdd88f761e9be9095ccbedf3e08d61ae216c643", "shasum": "" }, "require": { - "php": "~8.2.0 || ~8.3.0 || ~8.4.0", + "php": "~8.4.0 || ~8.5.0", "psr/clock": "^1.0" }, "provide": { "psr/clock-implementation": "1.0" }, "require-dev": { - "infection/infection": "^0.29", - "lcobucci/coding-standard": "^11.1.0", + "infection/infection": "^0.32", + "lcobucci/coding-standard": "^12.0", "phpstan/extension-installer": "^1.3.1", - "phpstan/phpstan": "^1.10.25", - "phpstan/phpstan-deprecation-rules": "^1.1.3", - "phpstan/phpstan-phpunit": "^1.3.13", - "phpstan/phpstan-strict-rules": "^1.5.1", - "phpunit/phpunit": "^11.3.6" + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^13.0" }, "type": "library", "autoload": { @@ -2964,7 +2965,7 @@ "description": "Yet another clock abstraction", "support": { "issues": "https://github.com/lcobucci/clock/issues", - "source": "https://github.com/lcobucci/clock/tree/3.3.1" + "source": "https://github.com/lcobucci/clock/tree/3.6.0" }, "funding": [ { @@ -2976,7 +2977,7 @@ "type": "patreon" } ], - "time": "2024-09-24T20:45:14+00:00" + "time": "2026-04-13T21:30:16+00:00" }, { "name": "lcobucci/jwt", @@ -7470,25 +7471,25 @@ }, { "name": "symfony/filesystem", - "version": "v7.4.11", + "version": "v8.0.11", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "d721ea61b4a5fba8c5b6e7c1feda19efea144b50" + "reference": "224db910898ce1317b892a9a1338f1f8f17eb7c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/d721ea61b4a5fba8c5b6e7c1feda19efea144b50", - "reference": "d721ea61b4a5fba8c5b6e7c1feda19efea144b50", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/224db910898ce1317b892a9a1338f1f8f17eb7c7", + "reference": "224db910898ce1317b892a9a1338f1f8f17eb7c7", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.4", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, "require-dev": { - "symfony/process": "^6.4|^7.0|^8.0" + "symfony/process": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -7516,7 +7517,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.4.11" + "source": "https://github.com/symfony/filesystem/tree/v8.0.11" }, "funding": [ { @@ -7536,7 +7537,7 @@ "type": "tidelift" } ], - "time": "2026-05-11T16:38:44+00:00" + "time": "2026-05-11T16:39:47+00:00" }, { "name": "symfony/finder", @@ -10702,11 +10703,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.54", + "version": "2.1.55", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8be50c3992107dc837b17da4d140fbbdf9a5c5bd", - "reference": "8be50c3992107dc837b17da4d140fbbdf9a5c5bd", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9eaac3826ed5e9b8427350a43cac825eeca3f566", + "reference": "9eaac3826ed5e9b8427350a43cac825eeca3f566", "shasum": "" }, "require": { @@ -10751,7 +10752,7 @@ "type": "github" } ], - "time": "2026-04-29T13:31:09+00:00" + "time": "2026-05-18T11:57:34+00:00" }, { "name": "phpunit/php-code-coverage", @@ -12379,7 +12380,7 @@ "platform": {}, "platform-dev": {}, "platform-overrides": { - "php": "8.2" + "php": "8.4" }, "plugin-api-version": "2.9.0" } From 5475557ac8b226ca97c0842b2166103bf2a22593 Mon Sep 17 00:00:00 2001 From: dena Date: Tue, 19 May 2026 16:34:06 +0200 Subject: [PATCH 7/8] run rector --- app/Console/Commands/Invitation/Create.php | 2 +- .../Commands/Invitation/CreateBulk.php | 2 +- app/Console/Commands/Invitation/Delete.php | 2 +- .../Commands/RebuildQueryserviceData.php | 4 ++-- app/Console/Kernel.php | 2 ++ app/Exceptions/Handler.php | 1 + app/Helper/DomainValidator.php | 9 ++------ app/Helper/ElasticSearchHelper.php | 11 +++------- app/Helper/InviteHelper.php | 10 ++------- app/Helper/MWTimestampHelper.php | 2 +- app/Http/Controllers/Auth/LoginController.php | 4 ++-- .../Controllers/Auth/RegisterController.php | 4 ++-- .../Backend/MediaWikiHostsController.php | 4 ++-- app/Http/Controllers/Backend/QsController.php | 4 ++-- app/Http/Controllers/ComplaintController.php | 4 ++-- .../ConversionMetricController.php | 4 ++-- .../DeletedWikiMetricsController.php | 5 +++-- app/Http/Controllers/WikiController.php | 19 ++++++---------- .../WikiEntityImportController.php | 6 ++--- app/Http/Controllers/WikiLogoController.php | 2 +- .../Controllers/WikiProfileController.php | 8 +++---- app/Http/Middleware/Authenticate.php | 3 ++- app/Http/Middleware/BackendAuth.php | 14 ++++++------ app/Http/Middleware/Throttle.php | 1 + .../Resources/ConversionMetricResource.php | 1 + app/Http/Resources/PublicWikiResource.php | 1 + app/Jobs/CirrusSearch/CirrusSearchJob.php | 6 ++--- app/Jobs/CirrusSearch/ForceSearchIndex.php | 14 +++++------- .../CirrusSearch/QueueSearchIndexBatches.php | 3 ++- app/Jobs/CreateQueryserviceBatchesJob.php | 4 ++-- app/Jobs/DeleteQueryserviceNamespaceJob.php | 6 ++--- app/Jobs/DeleteWikiDbJob.php | 6 ++--- app/Jobs/DeleteWikiDispatcherJob.php | 2 +- app/Jobs/DeleteWikiFinalizeJob.php | 6 ++--- app/Jobs/ElasticSearchAliasInit.php | 12 +++------- app/Jobs/ElasticSearchIndexDelete.php | 8 +++---- app/Jobs/KubernetesIngressCreate.php | 11 +++------- app/Jobs/KubernetesIngressDeleteJob.php | 8 +++---- app/Jobs/MediawikiInit.php | 14 +++--------- app/Jobs/MediawikiSandboxLoadData.php | 9 ++------ app/Jobs/MediawikiUpdate.php | 21 +++--------------- app/Jobs/PlatformStatsSummaryJob.php | 2 +- app/Jobs/ProcessMediaWikiJobsJob.php | 5 +---- .../ProvisionQueryserviceNamespaceJob.php | 5 +---- app/Jobs/ProvisionWikiDbJob.php | 13 +++++------ app/Jobs/RequeuePendingQsBatchesJob.php | 2 +- app/Jobs/SetWikiLogo.php | 14 +++--------- app/Jobs/SiteStatsUpdateJob.php | 8 +++---- app/Jobs/SpawnQueryserviceUpdaterJob.php | 9 +------- app/Jobs/UpdateQueryserviceAllowList.php | 2 +- app/Jobs/UserCreateJob.php | 10 +-------- .../UserVerificationCreateTokenAndSendJob.php | 18 +++------------ app/Jobs/WikiEntityImportJob.php | 10 ++++----- app/Notifications/ComplaintNotification.php | 15 ++----------- .../ComplaintNotificationExternal.php | 1 + app/Notifications/ContactNotification.php | 17 +++----------- .../EmailReverificationNotification.php | 16 ++++++-------- app/Notifications/EmptyWikiNotification.php | 6 ++--- .../ResetPasswordNotification.php | 18 +++++++-------- .../UserCreationNotification.php | 16 ++++++-------- app/Providers/AppServiceProvider.php | 1 + app/Providers/CollectorRegistryProvider.php | 19 ++++++++-------- .../DomainValidatorServiceProvider.php | 1 + app/Providers/EventServiceProvider.php | 2 ++ app/Providers/HorizonServiceProvider.php | 10 ++++----- .../KubernetesClientServiceProvider.php | 1 + app/Providers/ReCaptchaServiceProvider.php | 2 ++ app/Providers/RouteServiceProvider.php | 1 + app/QsBatch.php | 1 + app/Rules/ForbiddenSubdomainRule.php | 11 +++------- app/Rules/NonEmptyJsonRule.php | 2 +- app/Rules/ReCaptchaValidation.php | 14 +++++------- app/Rules/SettingCaptchaQuestions.php | 2 +- .../SettingWikibaseManifestEquivEntities.php | 4 ++-- app/Services/WikiUserEmailChecker.php | 2 +- app/TermsOfUseVersion.php | 1 + app/Traits/PageFetcher.php | 4 +--- app/User.php | 6 +++++ app/UserTermsOfUseAcceptance.php | 1 + app/Wiki.php | 5 ++--- app/WikiEntityImport.php | 1 + app/WikiLifecycleEvents.php | 1 + app/WikiNotificationSentRecord.php | 1 + config/horizon.php | 2 +- config/ide-helper.php | 4 ++-- config/queue.php | 2 +- config/trustedproxy.php | 15 +++++-------- config/wbstack.php | 4 ++-- .../vendor/notifications/email.blade.php | 12 ++++------ routes/general.php | 4 +--- .../Commands/RebuildQueryserviceDataTest.php | 6 ++--- .../QueueSearchIndexBatchesTest.php | 22 +++++++------------ tests/Jobs/DeleteWikiJobTest.php | 2 +- tests/Jobs/PlatformStatsSummaryJobTest.php | 6 ++--- tests/Jobs/SetWikiLogoTest.php | 10 ++++----- .../Jobs/UpdateQueryserviceAllowListTest.php | 2 +- tests/Jobs/UserTermsOfUseAcceptanceTest.php | 2 +- tests/Middleware/AuthenticateTest.php | 10 ++++----- tests/Middleware/LimitWikiAccessTest.php | 8 +++---- tests/Routes/Complaint/SendMessageTest.php | 2 +- tests/Routes/User/ForgotPasswordTest.php | 4 +--- .../Wiki/DeletedWikiMetricsControllerTest.php | 2 +- tests/TestCase.php | 1 + 103 files changed, 252 insertions(+), 407 deletions(-) diff --git a/app/Console/Commands/Invitation/Create.php b/app/Console/Commands/Invitation/Create.php index cc09c2da..d35c30f3 100644 --- a/app/Console/Commands/Invitation/Create.php +++ b/app/Console/Commands/Invitation/Create.php @@ -17,7 +17,7 @@ class Create extends Command { */ public function handle() { $code = trim($this->argument('code')); - $jobResult = (new InvitationCreateJob($code))->handle(); + $jobResult = new InvitationCreateJob($code)->handle(); if ($jobResult) { $this->line('Successfully created invitation: ' . $code); diff --git a/app/Console/Commands/Invitation/CreateBulk.php b/app/Console/Commands/Invitation/CreateBulk.php index 294241c4..3081580b 100644 --- a/app/Console/Commands/Invitation/CreateBulk.php +++ b/app/Console/Commands/Invitation/CreateBulk.php @@ -22,7 +22,7 @@ public function handle() { for ($i = 0; $i < $numCodes; $i++) { $code = $helper->generate(); - $jobResult = (new InvitationCreateJob($code))->handle(); + $jobResult = new InvitationCreateJob($code)->handle(); if ($jobResult) { $this->line('Successfully created invitation: ' . $code); diff --git a/app/Console/Commands/Invitation/Delete.php b/app/Console/Commands/Invitation/Delete.php index a115846d..982dd234 100644 --- a/app/Console/Commands/Invitation/Delete.php +++ b/app/Console/Commands/Invitation/Delete.php @@ -17,7 +17,7 @@ class Delete extends Command { */ public function handle() { $code = trim($this->argument('code')); - (new InvitationDeleteJob($code))->handle(); + new InvitationDeleteJob($code)->handle(); return 0; } diff --git a/app/Console/Commands/RebuildQueryserviceData.php b/app/Console/Commands/RebuildQueryserviceData.php index 8286950e..31458529 100644 --- a/app/Console/Commands/RebuildQueryserviceData.php +++ b/app/Console/Commands/RebuildQueryserviceData.php @@ -93,7 +93,7 @@ private function getEntitiesForWiki(Wiki $wiki): array { : []; $merged = array_merge($items, $properties, $lexemes); - $this->stripPrefixes($merged); + self::stripPrefixes($merged); return $merged; } @@ -111,7 +111,7 @@ private function getSparqlUrl(Wiki $wiki): string { private static function stripPrefixes(array &$items): void { foreach ($items as &$item) { - $e = explode(':', $item); + $e = explode(':', (string) $item); $item = end($e); } } diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index b4330d6a..ceeea987 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -24,6 +24,7 @@ class Kernel extends ConsoleKernel { /** * Define the application's command schedule. */ + #[\Override] protected function schedule(Schedule $schedule): void { // Make sure that the DB and QS pools are always populated somewhat. // This will create at most 1 new entry for each per minute... @@ -66,6 +67,7 @@ protected function schedule(Schedule $schedule): void { /** * Register the commands for the application. */ + #[\Override] protected function commands(): void { $this->load(__DIR__ . '/Commands'); $this->load(__DIR__ . '/Commands/User'); diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index dfdad9b3..2dd066ac 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -20,6 +20,7 @@ class Handler extends ExceptionHandler { /** * Register the exception handling callbacks for the application. */ + #[\Override] public function register(): void { $this->reportable(function (Throwable $e): void { (new ErrorReporting)->report($e); diff --git a/app/Helper/DomainValidator.php b/app/Helper/DomainValidator.php index f5bce577..020410ac 100644 --- a/app/Helper/DomainValidator.php +++ b/app/Helper/DomainValidator.php @@ -6,13 +6,8 @@ use Illuminate\Support\Facades\Validator; class DomainValidator { - public array $subdomainRules; - - public string $subDomainSuffix; - - public function __construct(string $subDomainSuffix, array $subdomainRules) { - $this->subDomainSuffix = $subDomainSuffix; - $this->subdomainRules = $subdomainRules; + public function __construct(public string $subDomainSuffix, public array $subdomainRules) + { } public function getValidator($domain): \Illuminate\Contracts\Validation\Validator { diff --git a/app/Helper/ElasticSearchHelper.php b/app/Helper/ElasticSearchHelper.php index 983ab8c3..0a56564a 100644 --- a/app/Helper/ElasticSearchHelper.php +++ b/app/Helper/ElasticSearchHelper.php @@ -5,13 +5,8 @@ use App\Http\Curl\HttpRequest; class ElasticSearchHelper { - private $elasticSearchHost; - - private $elasticSearchBaseName; - - public function __construct(string $elasticSearchHost, string $elasticSearchBaseName) { - $this->elasticSearchHost = $elasticSearchHost; - $this->elasticSearchBaseName = $elasticSearchBaseName; + public function __construct(private readonly string $elasticSearchHost, private readonly string $elasticSearchBaseName) + { } public function hasIndices(HttpRequest $request): bool { @@ -44,7 +39,7 @@ public function hasIndices(HttpRequest $request): bool { // index\n // site1.localhost_content_blabla\n // site1.localhost_general_bla\n - $wikiIndices = array_filter(explode("\n", $rawResponse)); + $wikiIndices = array_filter(explode("\n", (string) $rawResponse)); // no indices to delete only index header if (count($wikiIndices) <= 1) { diff --git a/app/Helper/InviteHelper.php b/app/Helper/InviteHelper.php index 618bed4f..eb15a63d 100644 --- a/app/Helper/InviteHelper.php +++ b/app/Helper/InviteHelper.php @@ -3,23 +3,17 @@ namespace App\Helper; class InviteHelper { - private $segments; - - private $segmentLength; - private $prefix; - public function __construct(int $numSegments = 2, int $segmentLength = 4) { + public function __construct(private readonly int $segments = 2, private readonly int $segmentLength = 4) { $this->prefix = 'wbcloud-'; - $this->segments = $numSegments; - $this->segmentLength = $segmentLength; } private function generateSegment(int &$counter): string { $segment = ''; for ($i = 0; $i < $this->segmentLength; $i++) { - $segment .= rand(0, 9); + $segment .= random_int(0, 9); } $counter++; diff --git a/app/Helper/MWTimestampHelper.php b/app/Helper/MWTimestampHelper.php index a5d03f71..758a71dc 100644 --- a/app/Helper/MWTimestampHelper.php +++ b/app/Helper/MWTimestampHelper.php @@ -12,7 +12,7 @@ use Carbon\Exceptions\InvalidFormatException; class MWTimestampHelper { - private const MWTimestampFormat = 'YmdHis'; + private const string MWTimestampFormat = 'YmdHis'; public static function getCarbonFromMWTimestamp(string $MWTimestamp): CarbonImmutable { $carbon = CarbonImmutable::createFromFormat(self::MWTimestampFormat, $MWTimestamp); diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 025aa53f..95e6879f 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -50,7 +50,7 @@ public function deleteLogin(Request $request) { return response() ->json() ->setStatusCode(204) - ->withCookie($this->deleteCookie()); + ->withCookie(self::deleteCookie()); } public function postLogin(Request $request): ?JsonResponse { @@ -84,7 +84,7 @@ public function postLogin(Request $request): ?JsonResponse { return response()->json([ 'user' => $user, // <- we're sending the user info for frontend usage ])->withCookie( - $this->getCookie($user->createToken('yourAppName')->accessToken) + self::getCookie($user->createToken('yourAppName')->accessToken) ); } else { $this->incrementLoginAttempts($request); diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index 566fa518..d517d193 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -33,10 +33,10 @@ public function register(Request $request) { $user = null; DB::transaction(function () use (&$user, $request): void { - $user = (new UserCreateJob( + $user = new UserCreateJob( $request->input('email'), $request->input('password') - ))->handle(); + )->handle(); (UserVerificationCreateTokenAndSendJob::newForAccountCreation($user))->handle(); }); diff --git a/app/Http/Controllers/Backend/MediaWikiHostsController.php b/app/Http/Controllers/Backend/MediaWikiHostsController.php index cf9311ef..93ed76fa 100644 --- a/app/Http/Controllers/Backend/MediaWikiHostsController.php +++ b/app/Http/Controllers/Backend/MediaWikiHostsController.php @@ -15,9 +15,9 @@ public function getWikiHostsForDomain(Request $request): JsonResponse { $domain = $request->query('domain'); try { $hosts = $mediawikiHostResolver->getHostsForDomain($domain); - } catch (UnknownWikiDomainException $e) { + } catch (UnknownWikiDomainException) { return response()->json(['error' => 'Domain not found.'], 404); - } catch (UnknownDBVersionException $e) { + } catch (UnknownDBVersionException) { return response()->json(['error' => 'Unknown database version.'], 500); } diff --git a/app/Http/Controllers/Backend/QsController.php b/app/Http/Controllers/Backend/QsController.php index 01c38ebb..3a11223a 100644 --- a/app/Http/Controllers/Backend/QsController.php +++ b/app/Http/Controllers/Backend/QsController.php @@ -36,7 +36,7 @@ public function getBatches(Request $request): Response { public function markBatchesDone(Request $request): Response { $batches = (array) $request->json()->all('batches'); - QsBatch::whereIn('id', $batches)->increment( + QsBatch::whereIn('id')->increment( 'processing_attempts', 1, ['done' => 1, 'pending_since' => null] ); @@ -46,7 +46,7 @@ public function markBatchesDone(Request $request): Response { public function markBatchesNotDone(Request $request): Response { $batches = (array) $request->json()->all('batches'); - QsBatch::whereIn('id', $batches)->increment( + QsBatch::whereIn('id')->increment( 'processing_attempts', 1, ['done' => 0, 'pending_since' => null] ); diff --git a/app/Http/Controllers/ComplaintController.php b/app/Http/Controllers/ComplaintController.php index 1253f911..d49b99ac 100644 --- a/app/Http/Controllers/ComplaintController.php +++ b/app/Http/Controllers/ComplaintController.php @@ -81,8 +81,8 @@ public function sendMessage(Request $request): JsonResponse { * Get a validator for an incoming complaint report page request. */ protected function validator(array $data): \Illuminate\Contracts\Validation\Validator { - $data['name'] = $data['name'] ?? ''; - $data['email'] = $data['email'] ?? ''; + $data['name'] ??= ''; + $data['email'] ??= ''; $validation = [ 'recaptcha' => ['required', 'string', 'bail', $this->recaptchaValidation], diff --git a/app/Http/Controllers/ConversionMetricController.php b/app/Http/Controllers/ConversionMetricController.php index 2074fa20..645d5391 100644 --- a/app/Http/Controllers/ConversionMetricController.php +++ b/app/Http/Controllers/ConversionMetricController.php @@ -68,9 +68,9 @@ public function index(Request $request) { private function returnCsv($output) { ob_start(); $handle = fopen('php://output', 'r+'); - fputcsv($handle, ['domain_name', 'time_to_engage_days', 'time_before_wiki_abandoned_days', 'number_of_active_editors', 'wiki_creation_time', 'first_edited_time', 'last_edited_time']); + fputcsv($handle, ['domain_name', 'time_to_engage_days', 'time_before_wiki_abandoned_days', 'number_of_active_editors', 'wiki_creation_time', 'first_edited_time', 'last_edited_time'], escape: '\\'); foreach ($output as $wikiMetrics) { - fputcsv($handle, array_values($wikiMetrics)); + fputcsv($handle, array_values($wikiMetrics), escape: '\\'); } $csv = ob_get_clean(); diff --git a/app/Http/Controllers/DeletedWikiMetricsController.php b/app/Http/Controllers/DeletedWikiMetricsController.php index 5992ac4e..c07b6e34 100644 --- a/app/Http/Controllers/DeletedWikiMetricsController.php +++ b/app/Http/Controllers/DeletedWikiMetricsController.php @@ -30,9 +30,10 @@ private function returnCsv($output) { 'number_of_users_for_wiki', 'wiki_creation_time', 'wiki_deletion_time', - ]); + ], + escape: '\\'); foreach ($output as $deletedWikiMetrics) { - fputcsv($handle, array_values($deletedWikiMetrics)); + fputcsv($handle, array_values($deletedWikiMetrics), escape: '\\'); } $csv = ob_get_clean(); diff --git a/app/Http/Controllers/WikiController.php b/app/Http/Controllers/WikiController.php index b5731bbc..b744d1ef 100644 --- a/app/Http/Controllers/WikiController.php +++ b/app/Http/Controllers/WikiController.php @@ -27,13 +27,8 @@ use Illuminate\Validation\Rule; class WikiController extends Controller { - private $domainValidator; - - private $profileValidator; - - public function __construct(DomainValidator $domainValidator, ProfileValidator $profileValidator) { - $this->profileValidator = $profileValidator; - $this->domainValidator = $domainValidator; + public function __construct(private readonly DomainValidator $domainValidator, private readonly ProfileValidator $profileValidator) + { } public function create(Request $request): Response { @@ -46,11 +41,11 @@ public function create(Request $request): Response { } $user = $request->user(); - $submittedDomain = strtolower($request->input('domain')); + $submittedDomain = strtolower((string) $request->input('domain')); $submittedDomain = DomainHelper::encode($submittedDomain); $domainValidator = $this->domainValidator->getValidator($submittedDomain); - $isSubdomain = $this->isSubDomain($submittedDomain); + $isSubdomain = static::isSubDomain($submittedDomain); $domainValidator->validateWithBag('post'); @@ -72,7 +67,7 @@ public function create(Request $request): Response { $rawProfile = false; if ($request->filled('profile')) { - $rawProfile = json_decode($request->input('profile'), true); + $rawProfile = json_decode((string) $request->input('profile'), true); $profileValidator = $this->profileValidator->getValidator($rawProfile); $profileValidator->validateWithBag('post'); } @@ -240,8 +235,8 @@ public function getWikiDetailsForIdForOwner(Request $request): Response { } public static function isSubDomain(string $domain, ?string $subDomainSuffix = null): bool { - $subDomainSuffix = $subDomainSuffix ?? Config::get('wbstack.subdomain_suffix'); + $subDomainSuffix ??= Config::get('wbstack.subdomain_suffix'); - return preg_match('/' . preg_quote($subDomainSuffix) . '$/', $domain) === 1; + return preg_match('/' . preg_quote((string) $subDomainSuffix) . '$/', $domain) === 1; } } diff --git a/app/Http/Controllers/WikiEntityImportController.php b/app/Http/Controllers/WikiEntityImportController.php index 684c63f3..ba2f0709 100644 --- a/app/Http/Controllers/WikiEntityImportController.php +++ b/app/Http/Controllers/WikiEntityImportController.php @@ -13,9 +13,9 @@ use Prometheus\Counter; class WikiEntityImportController extends Controller { - private Counter $successfulCounter; + private readonly Counter $successfulCounter; - private Counter $failedCounter; + private readonly Counter $failedCounter; public function __construct(CollectorRegistry $registry) { $this->successfulCounter = $registry->getOrRegisterCounter( @@ -75,7 +75,7 @@ public function create(Request $request): JsonResponse { wikiId: $wiki->id, sourceWikiUrl: $validatedInput['source_wiki_url'], importId: $import->id, - entityIds: explode(',', $validatedInput['entity_ids']), + entityIds: explode(',', (string) $validatedInput['entity_ids']), )); return response()->json(['data' => $import]); diff --git a/app/Http/Controllers/WikiLogoController.php b/app/Http/Controllers/WikiLogoController.php index c06f01f3..08791e28 100644 --- a/app/Http/Controllers/WikiLogoController.php +++ b/app/Http/Controllers/WikiLogoController.php @@ -24,7 +24,7 @@ public function update(Request $request) { $wiki = $request->attributes->get('wiki'); // run the job to set the wiki logo - (new SetWikiLogo('id', $wiki->id, $request->file('logo')->getRealPath()))->handle(); + new SetWikiLogo('id', $wiki->id, $request->file('logo')->getRealPath())->handle(); // get the logo URL from the settings $wgLogoSetting = $wiki->settings()->firstWhere(['name' => WikiSetting::wgLogo])->value; diff --git a/app/Http/Controllers/WikiProfileController.php b/app/Http/Controllers/WikiProfileController.php index aa4a0882..07e2e012 100644 --- a/app/Http/Controllers/WikiProfileController.php +++ b/app/Http/Controllers/WikiProfileController.php @@ -9,10 +9,8 @@ use Illuminate\Http\Request; class WikiProfileController extends Controller { - private $profileValidator; - - public function __construct(ProfileValidator $profileValidator) { - $this->profileValidator = $profileValidator; + public function __construct(private readonly ProfileValidator $profileValidator) + { } public function create(Request $request): JsonResponse { @@ -21,7 +19,7 @@ public function create(Request $request): JsonResponse { 'profile' => ['required', 'json', new NonEmptyJsonRule], ]); - $rawProfile = json_decode($validatedInput['profile'], true); + $rawProfile = json_decode((string) $validatedInput['profile'], true); $profileValidator = $this->profileValidator->getValidator($rawProfile); $profileValidator->validateWithBag('post'); diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index 61917e20..582229ab 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -8,6 +8,7 @@ use Illuminate\Support\Facades\Config; class Authenticate extends Middleware { + #[\Override] public function handle($request, Closure $next, ...$guards) { try { // Passport wants to read tokens from Authorization headers, so @@ -19,7 +20,7 @@ public function handle($request, Closure $next, ...$guards) { $request->headers->set('Authorization', 'Bearer ' . $token); } $this->authenticate($request, $guards); - } catch (AuthenticationException $e) { + } catch (AuthenticationException) { // The "Unauthenticated." message is relied on by the UI to detect logged out state and cleanup its data // If this changes then the UI also needs to change.. return response()->json([ diff --git a/app/Http/Middleware/BackendAuth.php b/app/Http/Middleware/BackendAuth.php index 93a4a2b8..c4870d6c 100644 --- a/app/Http/Middleware/BackendAuth.php +++ b/app/Http/Middleware/BackendAuth.php @@ -7,18 +7,18 @@ use Illuminate\Http\Request; class BackendAuth { - /** - * The authentication guard factory instance. - */ - protected Auth $auth; - /** * Create a new middleware instance. * * @return void */ - public function __construct(Auth $auth) { - $this->auth = $auth; + public function __construct( + /** + * The authentication guard factory instance. + */ + protected Auth $auth + ) + { } /** diff --git a/app/Http/Middleware/Throttle.php b/app/Http/Middleware/Throttle.php index 8cd48831..0971b0fa 100644 --- a/app/Http/Middleware/Throttle.php +++ b/app/Http/Middleware/Throttle.php @@ -20,6 +20,7 @@ class Throttle extends ThrottleRequests { * * @throws ThrottleRequestsException */ + #[\Override] public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes = 1, $prefix = '') { if (config('app.env') === 'local') { return $next($request); diff --git a/app/Http/Resources/ConversionMetricResource.php b/app/Http/Resources/ConversionMetricResource.php index c015c92f..af7ce9c7 100644 --- a/app/Http/Resources/ConversionMetricResource.php +++ b/app/Http/Resources/ConversionMetricResource.php @@ -5,6 +5,7 @@ use Illuminate\Http\Resources\Json\JsonResource; class ConversionMetricResource extends JsonResource { + #[\Override] public function toArray($request): array { return [ 'id' => $this->id, diff --git a/app/Http/Resources/PublicWikiResource.php b/app/Http/Resources/PublicWikiResource.php index 37e1e92e..e6c2fbf2 100644 --- a/app/Http/Resources/PublicWikiResource.php +++ b/app/Http/Resources/PublicWikiResource.php @@ -5,6 +5,7 @@ use Illuminate\Http\Resources\Json\JsonResource; class PublicWikiResource extends JsonResource { + #[\Override] public function toArray($request): array { $logoSetting = $this->settings()->where('name', 'wgLogo')->first(); diff --git a/app/Jobs/CirrusSearch/CirrusSearchJob.php b/app/Jobs/CirrusSearch/CirrusSearchJob.php index ce6d6bad..938ba1e9 100644 --- a/app/Jobs/CirrusSearch/CirrusSearchJob.php +++ b/app/Jobs/CirrusSearch/CirrusSearchJob.php @@ -10,8 +10,6 @@ use Illuminate\Contracts\Queue\ShouldBeUnique; abstract class CirrusSearchJob extends Job implements ShouldBeUnique { - protected $wikiId; - protected $setting; protected $wiki; @@ -22,8 +20,8 @@ abstract public function apiModule(): string; abstract public function handleResponse(string $rawResponse, $error): void; - public function __construct($wikiId) { - $this->wikiId = $wikiId; + public function __construct(protected $wikiId) + { } /** diff --git a/app/Jobs/CirrusSearch/ForceSearchIndex.php b/app/Jobs/CirrusSearch/ForceSearchIndex.php index 7377d888..095cee8b 100644 --- a/app/Jobs/CirrusSearch/ForceSearchIndex.php +++ b/app/Jobs/CirrusSearch/ForceSearchIndex.php @@ -13,18 +13,12 @@ * php artisan job:dispatch CirrusSearch\\ForceSearchIndex id 1 0 1000 */ class ForceSearchIndex extends CirrusSearchJob { - private $fromId; - - private $toId; - - public function __construct(string $selectCol, $selectValue, int $fromId, int $toId) { + public function __construct(string $selectCol, $selectValue, private readonly int $fromId, private readonly int $toId) { $wiki = Wiki::where($selectCol, $selectValue)->firstOrFail(); - - $this->fromId = $fromId; - $this->toId = $toId; parent::__construct($wiki->id); } + #[\Override] public function uniqueId() { return parent::uniqueId() . '_' . $this->fromId . '_' @@ -43,6 +37,7 @@ public function apiModule(): string { return 'wbstackForceSearchIndex'; } + #[\Override] protected function getRequestTimeout(): int { return 1000; } @@ -62,7 +57,7 @@ public function handleResponse(string $rawResponse, $error): void { $successMatches = []; $lastElement = end($output); - preg_match('/Indexed a total of (\d+) pages/', $lastElement, $successMatches, PREG_OFFSET_CAPTURE); + preg_match('/Indexed a total of (\d+) pages/', (string) $lastElement, $successMatches, PREG_OFFSET_CAPTURE); if (count($successMatches) === 2 && is_numeric($successMatches[1][0])) { $numIndexedPages = intval($successMatches[1][0]); @@ -77,6 +72,7 @@ public function handleResponse(string $rawResponse, $error): void { /** * @return string */ + #[\Override] protected function getQueryParams() { return parent::getQueryParams() . '&fromId=' . $this->fromId . '&toId=' . $this->toId; } diff --git a/app/Jobs/CirrusSearch/QueueSearchIndexBatches.php b/app/Jobs/CirrusSearch/QueueSearchIndexBatches.php index 2ef3c9ea..13fef7a1 100644 --- a/app/Jobs/CirrusSearch/QueueSearchIndexBatches.php +++ b/app/Jobs/CirrusSearch/QueueSearchIndexBatches.php @@ -19,6 +19,7 @@ public function apiModule(): string { return 'wbstackQueueSearchIndexBatches'; } + #[\Override] protected function getRequestTimeout(): int { return 1000; } @@ -29,7 +30,7 @@ public function convertToBatch($output): array { foreach ($output as $command) { $matches = []; - preg_match('/--fromId (\d+) --toId (\d+)/', $command, $matches, PREG_OFFSET_CAPTURE); + preg_match('/--fromId (\d+) --toId (\d+)/', (string) $command, $matches, PREG_OFFSET_CAPTURE); if (count($matches) !== 3) { throw new \RuntimeException('Got some weird output from the script: ' . $command); diff --git a/app/Jobs/CreateQueryserviceBatchesJob.php b/app/Jobs/CreateQueryserviceBatchesJob.php index 977c36d4..5f87ca58 100644 --- a/app/Jobs/CreateQueryserviceBatchesJob.php +++ b/app/Jobs/CreateQueryserviceBatchesJob.php @@ -12,7 +12,7 @@ use Illuminate\Support\Facades\Log; class CreateQueryserviceBatchesJob extends Job { - private int $entityLimit; + private readonly int $entityLimit; public $timeout = 3600; @@ -80,7 +80,7 @@ private function tryToAppendEntitesToExistingBatches(array $entityIdsFromEvents, ->get(); foreach ($notDoneBatches as $qsBatch) { - $entitiesOnBatch = explode(',', $qsBatch->entityIds); + $entitiesOnBatch = explode(',', (string) $qsBatch->entityIds); $tentativeMerge = array_unique(array_merge($entityIdsFromEvents, $entitiesOnBatch)); if (count($tentativeMerge) > $this->entityLimit) { diff --git a/app/Jobs/DeleteQueryserviceNamespaceJob.php b/app/Jobs/DeleteQueryserviceNamespaceJob.php index ebf0297a..1a3298c5 100644 --- a/app/Jobs/DeleteQueryserviceNamespaceJob.php +++ b/app/Jobs/DeleteQueryserviceNamespaceJob.php @@ -8,13 +8,11 @@ use Illuminate\Contracts\Queue\ShouldBeUnique; class DeleteQueryserviceNamespaceJob extends Job implements ShouldBeUnique { - private $wikiId; - /** * @return void */ - public function __construct($wikiId) { - $this->wikiId = $wikiId; + public function __construct(private $wikiId) + { } /** diff --git a/app/Jobs/DeleteWikiDbJob.php b/app/Jobs/DeleteWikiDbJob.php index e6f0d594..c85da422 100644 --- a/app/Jobs/DeleteWikiDbJob.php +++ b/app/Jobs/DeleteWikiDbJob.php @@ -13,13 +13,11 @@ * Prepends the MW Database, User with `deleted_` prefix and deletes WikiDB relation for a wiki */ class DeleteWikiDbJob extends Job implements ShouldBeUnique { - private $wikiId; - /** * @return void */ - public function __construct(int $wikiId) { - $this->wikiId = $wikiId; + public function __construct(private readonly int $wikiId) + { } /** diff --git a/app/Jobs/DeleteWikiDispatcherJob.php b/app/Jobs/DeleteWikiDispatcherJob.php index d1689272..2f906f8f 100644 --- a/app/Jobs/DeleteWikiDispatcherJob.php +++ b/app/Jobs/DeleteWikiDispatcherJob.php @@ -67,7 +67,7 @@ public function handle() { // deletes any settings, managers and the wiki itself $jobs[] = new DeleteWikiFinalizeJob($wiki->id); - $logMessage = implode(',', array_map('get_class', $jobs)); + $logMessage = implode(',', array_map(get_class(...), $jobs)); Log::info(__METHOD__ . ": Dispatching hard delete job chain for id: {$wiki->id}, jobs: {$logMessage}."); Bus::chain([ diff --git a/app/Jobs/DeleteWikiFinalizeJob.php b/app/Jobs/DeleteWikiFinalizeJob.php index 38358204..ea8203bf 100644 --- a/app/Jobs/DeleteWikiFinalizeJob.php +++ b/app/Jobs/DeleteWikiFinalizeJob.php @@ -13,13 +13,11 @@ use Illuminate\Support\Facades\Storage; class DeleteWikiFinalizeJob extends Job implements ShouldBeUnique { - private $wikiId; - /** * @return void */ - public function __construct($wikiId) { - $this->wikiId = $wikiId; + public function __construct(private $wikiId) + { } /** diff --git a/app/Jobs/ElasticSearchAliasInit.php b/app/Jobs/ElasticSearchAliasInit.php index 784dabea..4be368e9 100644 --- a/app/Jobs/ElasticSearchAliasInit.php +++ b/app/Jobs/ElasticSearchAliasInit.php @@ -11,10 +11,6 @@ class ElasticSearchAliasInit extends Job { use Dispatchable; - public readonly int $wikiId; - - public readonly string $esHost; - private $dbName; public readonly string $sharedPrefix; @@ -23,9 +19,7 @@ class ElasticSearchAliasInit extends Job { // https://laravel.com/docs/10.x/queues#max-attempts public int $tries = 0; - public function __construct(int $wikiId, string $esHost, ?string $sharedPrefix = null) { - $this->wikiId = $wikiId; - $this->esHost = $esHost; + public function __construct(public readonly int $wikiId, public readonly string $esHost, ?string $sharedPrefix = null) { $this->sharedPrefix = $sharedPrefix ?? getenv('ELASTICSEARCH_SHARED_INDEX_PREFIX'); } @@ -38,7 +32,7 @@ public function middleware(): array { return [ // Only allow one job per ES host to run at a time to avoid DoSing the ES cluster with alias updates. // This job will only be retried after 15 seconds if another job for the same ES host is currently running. - (new WithoutOverlapping("elasticsearch-alias-init-{$this->esHost}"))->releaseAfter(15), + new WithoutOverlapping("elasticsearch-alias-init-{$this->esHost}")->releaseAfter(15), ]; } @@ -111,7 +105,7 @@ public function handle(HttpRequest $request) { return; } - $json = json_decode($rawResponse, true); + $json = json_decode((string) $rawResponse, true); if (!array_key_exists('acknowledged', $json)) { Log::error("Missing 'acknowledged' key. Are the shared indices set up properly?"); $this->fail( diff --git a/app/Jobs/ElasticSearchIndexDelete.php b/app/Jobs/ElasticSearchIndexDelete.php index 2b69ca08..031ef1ae 100644 --- a/app/Jobs/ElasticSearchIndexDelete.php +++ b/app/Jobs/ElasticSearchIndexDelete.php @@ -10,13 +10,11 @@ use Illuminate\Support\Facades\Config; class ElasticSearchIndexDelete extends Job implements ShouldBeUnique { - private $wikiId; - /** * @return void */ - public function __construct(int $wikiId) { - $this->wikiId = $wikiId; + public function __construct(private readonly int $wikiId) + { } /** @@ -115,7 +113,7 @@ public function handle(HttpRequest $request) { continue; } - $response = json_decode($rawResponse, true); + $response = json_decode((string) $rawResponse, true); if (!is_array($response) || !array_key_exists('acknowledged', $response) || $response['acknowledged'] !== true) { $this->fail(new \RuntimeException('ElasticSearchIndexDelete job for ' . $this->wikiId . ' was not successful: ' . $rawResponse)); diff --git a/app/Jobs/KubernetesIngressCreate.php b/app/Jobs/KubernetesIngressCreate.php index c7e148ee..287007cd 100644 --- a/app/Jobs/KubernetesIngressCreate.php +++ b/app/Jobs/KubernetesIngressCreate.php @@ -13,17 +13,12 @@ * If you need to cleanup a test run of this you need to remove the ingress and the related secret */ class KubernetesIngressCreate extends Job { - private $id; - - private $wikiDomain; - /** - * @param int|string $wikiId + * @param int|string $id * @param string $wikiDomain */ - public function __construct($wikiId, $wikiDomain) { - $this->id = $wikiId; - $this->wikiDomain = $wikiDomain; + public function __construct(private $id, private $wikiDomain) + { } public static function getKubernetesIngressName($wikiId): string { diff --git a/app/Jobs/KubernetesIngressDeleteJob.php b/app/Jobs/KubernetesIngressDeleteJob.php index 51fe9e1d..b22062ab 100644 --- a/app/Jobs/KubernetesIngressDeleteJob.php +++ b/app/Jobs/KubernetesIngressDeleteJob.php @@ -9,15 +9,13 @@ * Job for deleting a wikis kubernetes ingress */ class KubernetesIngressDeleteJob extends Job { - private $id; - private $wikiDomain; /** - * @param int|string $wikiId + * @param int|string $id */ - public function __construct($wikiId) { - $this->id = $wikiId; + public function __construct(private $id) + { } /** diff --git a/app/Jobs/MediawikiInit.php b/app/Jobs/MediawikiInit.php index 76bb5b4e..e5668f5a 100644 --- a/app/Jobs/MediawikiInit.php +++ b/app/Jobs/MediawikiInit.php @@ -6,19 +6,11 @@ use App\Services\MediaWikiHostResolver; class MediawikiInit extends Job { - private $wikiDomain; - - private $username; - - private $email; - /** * @return void */ - public function __construct($wikiDomain, $username, $email) { - $this->wikiDomain = $wikiDomain; - $this->username = $username; - $this->email = $email; + public function __construct(private $wikiDomain, private $username, private $email) + { } /** @@ -52,7 +44,7 @@ public function handle(HttpRequest $request, MediaWikiHostResolver $mwHostResolv throw new \RuntimeException('curl error for ' . $this->wikiDomain . ': ' . $err); } - $response = json_decode($rawResponse, true); + $response = json_decode((string) $rawResponse, true); if (!is_array($response) || !array_key_exists('wbstackInit', $response)) { throw new \RuntimeException('wbstackInit call for ' . $this->wikiDomain . '. No wbstackInit key in response: ' . $rawResponse); diff --git a/app/Jobs/MediawikiSandboxLoadData.php b/app/Jobs/MediawikiSandboxLoadData.php index 8d294432..42a8dd04 100644 --- a/app/Jobs/MediawikiSandboxLoadData.php +++ b/app/Jobs/MediawikiSandboxLoadData.php @@ -5,16 +5,11 @@ use App\Services\MediaWikiHostResolver; class MediawikiSandboxLoadData extends Job { - private $wikiDomain; - - private $dataSet; - /** * @return void */ - public function __construct($wikiDomain, $dataSet) { - $this->wikiDomain = $wikiDomain; - $this->dataSet = $dataSet; + public function __construct(private $wikiDomain, private $dataSet) + { } /** diff --git a/app/Jobs/MediawikiUpdate.php b/app/Jobs/MediawikiUpdate.php index ff708d34..4c10df9b 100644 --- a/app/Jobs/MediawikiUpdate.php +++ b/app/Jobs/MediawikiUpdate.php @@ -24,16 +24,6 @@ * for i in {1..10}; do php artisan job:dispatchNow MediawikiUpdate wiki_dbs.version mw1.34-wbs1 mw1.34-wbs1 mw1.35-wbs1 mediawiki-135; done */ class MediawikiUpdate extends Job { - private $selectCol; - - private $selectValue; - - private $targetBackendHost; - - private $from; - - private $to; - /** * @param string $selectCol Selection field in the wiki_dbs table e.g. "wiki_id" * @param string $selectValue Selection value in the wiki_dbs table e.g. "38" @@ -41,13 +31,8 @@ class MediawikiUpdate extends Job { * @param string $to The version of schema to say we updated to * @param string $targetBackendHost the backend API hosts to hit (as they are versioned) */ - public function __construct($selectCol, $selectValue, $from, $to, $targetBackendHost) { - $this->selectCol = $selectCol; - $this->selectValue = $selectValue; - $this->from = $from; - $this->to = $to; - // TODO in an ideal world the target backend would be known by the application somehow? - $this->targetBackendHost = $targetBackendHost; + public function __construct(private $selectCol, private $selectValue, private $from, private $to, private $targetBackendHost) + { } /** @@ -108,7 +93,7 @@ public function handle() { // Look for "Done in" in the response to see success... // This is normally the last line of update.php output - $success = strstr(end($response['output']), 'Done in ') && $response['return'] == 0; + $success = strstr((string) end($response['output']), 'Done in ') && $response['return'] == 0; // Update the DB version if successfull if ($success) { diff --git a/app/Jobs/PlatformStatsSummaryJob.php b/app/Jobs/PlatformStatsSummaryJob.php index 7bede260..fbb4445c 100644 --- a/app/Jobs/PlatformStatsSummaryJob.php +++ b/app/Jobs/PlatformStatsSummaryJob.php @@ -98,7 +98,7 @@ public function prepareStats(array $allStats, $wikis): array { try { $nextPropertyCount = count($this->fetchPagesInNamespace($wiki->domain, MediawikiNamespace::property)); array_push($propertiesCount, $nextPropertyCount); - } catch (\Exception $ex) { + } catch (\Exception) { Log::warning('Failed to fetch property count for wiki ' . $wiki->domain . ', will use 0 instead.'); } diff --git a/app/Jobs/ProcessMediaWikiJobsJob.php b/app/Jobs/ProcessMediaWikiJobsJob.php index 7fdb3267..be63ee9b 100644 --- a/app/Jobs/ProcessMediaWikiJobsJob.php +++ b/app/Jobs/ProcessMediaWikiJobsJob.php @@ -15,12 +15,9 @@ class ProcessMediaWikiJobsJob implements ShouldBeUnique, ShouldQueue { use InteractsWithQueue, Queueable; - private string $wikiDomain; - private string $jobsKubernetesNamespace; - public function __construct(string $wikiDomain) { - $this->wikiDomain = $wikiDomain; + public function __construct(private string $wikiDomain) { $this->jobsKubernetesNamespace = Config::get('wbstack.api_job_namespace'); } diff --git a/app/Jobs/ProvisionQueryserviceNamespaceJob.php b/app/Jobs/ProvisionQueryserviceNamespaceJob.php index 3da47ed1..9da27d15 100644 --- a/app/Jobs/ProvisionQueryserviceNamespaceJob.php +++ b/app/Jobs/ProvisionQueryserviceNamespaceJob.php @@ -13,12 +13,10 @@ class ProvisionQueryserviceNamespaceJob extends Job { private $namespace; - private $maxFree; - /** * @return void */ - public function __construct($namespace = null, $maxFree = null) { + public function __construct($namespace = null, private $maxFree = null) { if ($namespace !== null && preg_match('/[^A-Za-z0-9]/', $namespace)) { throw new \InvalidArgumentException('$namespace must only contain [^A-Za-z0-9] or null, got ' . $namespace); } @@ -30,7 +28,6 @@ public function __construct($namespace = null, $maxFree = null) { } $this->namespace = $namespace; - $this->maxFree = $maxFree; } private function doesMaxFreeSayWeShouldStop(): bool { diff --git a/app/Jobs/ProvisionWikiDbJob.php b/app/Jobs/ProvisionWikiDbJob.php index b51d2302..a2962ace 100644 --- a/app/Jobs/ProvisionWikiDbJob.php +++ b/app/Jobs/ProvisionWikiDbJob.php @@ -28,13 +28,11 @@ class ProvisionWikiDbJob extends Job { private $dbPassword; - private $maxFree; - /** * @return void */ - public function __construct($prefix = null, $dbName = false, $maxFree = null) { - if (preg_match('/[^A-Za-z0-9\-_]/', $prefix)) { + public function __construct($prefix = null, $dbName = false, private $maxFree = null) { + if (preg_match('/[^A-Za-z0-9\-_]/', (string) $prefix)) { throw new \InvalidArgumentException('Prefix must only contain [^A-Za-z0-9\-_], got ' . $prefix); } @@ -59,7 +57,6 @@ public function __construct($prefix = null, $dbName = false, $maxFree = null) { $this->prefix = $prefix; $this->dbName = $dbName; - $this->maxFree = $maxFree; $this->newSqlFile = config('wbstack.wiki_db_provision_version'); } @@ -100,7 +97,7 @@ public function handle(DatabaseManager $manager) { // So, catch this exception and check the error state ourselves, and allow us to continue past this? try { $conn->statement("CREATE USER '" . $this->dbUser . "'@'%' IDENTIFIED BY '" . $this->dbPassword . "'"); - } catch (QueryException $e) { + } catch (QueryException) { // Probably fine, and if not fine then the ALTER will fail below? :) $conn->statement("ALTER USER '" . $this->dbUser . "'@'%' IDENTIFIED BY '" . $this->dbPassword . "'"); } @@ -140,7 +137,7 @@ public function handle(DatabaseManager $manager) { // Figure out the SQL version $stmt = $pdo->query('SELECT version() AS version'); $fullVersion = $stmt->fetch()['version']; // "10.5.12-MariaDB-log" - preg_match('/^(\d+\.\d+\.\d+)(?!\d).*?$/', $fullVersion, $versionMatches); // [ 0 => '10.5.12-MariaDB-log', 1 => '10.5.12' ] + preg_match('/^(\d+\.\d+\.\d+)(?!\d).*?$/', (string) $fullVersion, $versionMatches); // [ 0 => '10.5.12-MariaDB-log', 1 => '10.5.12' ] $sqlVersion = $versionMatches[1]; // '10.5.12' $aboveMariaDb1059 = version_compare($sqlVersion, '10.5.9'); // 1 = higher, 0 = same, -1 = lower $aboveMariaDb1052 = version_compare($sqlVersion, '10.5.2'); // 1 = higher, 0 = same, -1 = lower @@ -182,7 +179,7 @@ public function handle(DatabaseManager $manager) { $sqlParts = explode("\n\n", $prefixedSql); foreach ($sqlParts as $part) { - if (strpos($part, '--') === 0) { + if (str_starts_with($part, '--')) { // Skip comment blocks continue; } diff --git a/app/Jobs/RequeuePendingQsBatchesJob.php b/app/Jobs/RequeuePendingQsBatchesJob.php index 1f063c12..4cec9ff5 100644 --- a/app/Jobs/RequeuePendingQsBatchesJob.php +++ b/app/Jobs/RequeuePendingQsBatchesJob.php @@ -38,7 +38,7 @@ private function markBatchesFailed(): array { ->get() ->pluck('id') ->toArray(); - QsBatch::whereIn('id', $failedBatches)->update([ + QsBatch::whereIn('id')->update([ 'failed' => true, 'pending_since' => null, ]); diff --git a/app/Jobs/SetWikiLogo.php b/app/Jobs/SetWikiLogo.php index 2aa4b029..3c6b280c 100644 --- a/app/Jobs/SetWikiLogo.php +++ b/app/Jobs/SetWikiLogo.php @@ -18,16 +18,8 @@ * NOTE: This job needs to be run as the correct user if run via artisan (instead of via the UI) */ class SetWikiLogo extends Job { - private $wikiKey; - - private $wikiValue; - - private $logoPath; - - public function __construct(string $wikiKey, string $wikiValue, string $logoPath) { - $this->wikiKey = $wikiKey; - $this->wikiValue = $wikiValue; - $this->logoPath = $logoPath; + public function __construct(private readonly string $wikiKey, private readonly string $wikiValue, private readonly string $logoPath) + { } public function handle(): void { @@ -48,7 +40,7 @@ public function handle(): void { return; // safeguard } - } catch (QueryException $e) { + } catch (QueryException) { $this->fail(new \InvalidArgumentException("Invalid key ({$this->wikiKey}) or value ({$this->wikiValue})")); return; // safeguard diff --git a/app/Jobs/SiteStatsUpdateJob.php b/app/Jobs/SiteStatsUpdateJob.php index d16afcdd..7d5bf2e2 100644 --- a/app/Jobs/SiteStatsUpdateJob.php +++ b/app/Jobs/SiteStatsUpdateJob.php @@ -17,10 +17,8 @@ class SiteStatsUpdateJob extends Job { use Batchable; - private $wiki_id; - - public function __construct($wiki_id) { - $this->wiki_id = $wiki_id; + public function __construct(private $wiki_id) + { } public function handle(HttpRequest $request, MediaWikiHostResolver $mwHostResolver): void { @@ -59,7 +57,7 @@ public function handle(HttpRequest $request, MediaWikiHostResolver $mwHostResolv return; // safegaurd } - $response = json_decode($rawResponse, true); + $response = json_decode((string) $rawResponse, true); if (!is_array($response) || !array_key_exists('wbstackSiteStatsUpdate', $response)) { $this->fail( diff --git a/app/Jobs/SpawnQueryserviceUpdaterJob.php b/app/Jobs/SpawnQueryserviceUpdaterJob.php index 92523643..3f126ea7 100644 --- a/app/Jobs/SpawnQueryserviceUpdaterJob.php +++ b/app/Jobs/SpawnQueryserviceUpdaterJob.php @@ -14,21 +14,14 @@ class SpawnQueryserviceUpdaterJob implements ShouldBeUnique, ShouldQueue { use InteractsWithQueue, Queueable; - public string $wikiDomain; - public string $entities; - public string $sparqlUrl; - public string $qsKubernetesNamespace; - public function __construct(string $wikiDomain, string $entities, string $sparqlUrl) { + public function __construct(public string $wikiDomain, string $entities, public string $sparqlUrl) { $sortedEntities = explode(',', $entities); asort($sortedEntities); - - $this->wikiDomain = $wikiDomain; $this->entities = implode(',', $sortedEntities); - $this->sparqlUrl = $sparqlUrl; $this->qsKubernetesNamespace = Config::get('wbstack.qs_job_namespace'); } diff --git a/app/Jobs/UpdateQueryserviceAllowList.php b/app/Jobs/UpdateQueryserviceAllowList.php index c5f47d48..fa1ae767 100644 --- a/app/Jobs/UpdateQueryserviceAllowList.php +++ b/app/Jobs/UpdateQueryserviceAllowList.php @@ -37,7 +37,7 @@ public function handle(Client $k8s) { $config = $config->toArray(); if (array_key_exists($allowListStaticKey, $config['data'])) { - $allowList .= PHP_EOL . trim($config['data'][$allowListStaticKey]); + $allowList .= PHP_EOL . trim((string) $config['data'][$allowListStaticKey]); } $config['data'][$allowListKey] = trim($allowList); $k8s->configMaps()->update(new ConfigMap($config)); diff --git a/app/Jobs/UserCreateJob.php b/app/Jobs/UserCreateJob.php index 42c0742a..5e11b967 100644 --- a/app/Jobs/UserCreateJob.php +++ b/app/Jobs/UserCreateJob.php @@ -9,17 +9,9 @@ use Illuminate\Support\Facades\Log; class UserCreateJob extends Job { - private $email; - - private $password; - private $verified; - public function __construct($email, $password, $verified = false) { - // TODO maybe pass in an unsaved eloquent model? - // // but that would make CLI job creation hard - $this->email = $email; - $this->password = $password; + public function __construct(private $email, private $password, $verified = false) { $this->verified = false; } diff --git a/app/Jobs/UserVerificationCreateTokenAndSendJob.php b/app/Jobs/UserVerificationCreateTokenAndSendJob.php index 8b350522..e201e5ec 100644 --- a/app/Jobs/UserVerificationCreateTokenAndSendJob.php +++ b/app/Jobs/UserVerificationCreateTokenAndSendJob.php @@ -8,16 +8,6 @@ use App\UserVerificationToken; class UserVerificationCreateTokenAndSendJob extends Job { - /** - * @var User - */ - private $user; - - /** - * @var string - */ - private $notificationClass; - public static function newForAccountCreation(User $user): self { return new self($user, UserCreationNotification::class); } @@ -29,11 +19,9 @@ public static function newForReverification(User $user): self { /** * @return void */ - public function __construct(User $user, string $notificationClass) { - $this->user = $user; - $this->notificationClass = $notificationClass; - if (!class_exists($notificationClass)) { - throw new \InvalidArgumentException("$notificationClass not found for notification"); + public function __construct(private readonly User $user, private readonly string $notificationClass) { + if (!class_exists($this->notificationClass)) { + throw new \InvalidArgumentException("{$this->notificationClass} not found for notification"); } } diff --git a/app/Jobs/WikiEntityImportJob.php b/app/Jobs/WikiEntityImportJob.php index aa069629..2583b4aa 100644 --- a/app/Jobs/WikiEntityImportJob.php +++ b/app/Jobs/WikiEntityImportJob.php @@ -38,9 +38,9 @@ public function handle(Client $kubernetesClient, MediaWikiHostResolver $mwHostRe try { $wiki = Wiki::findOrFail($this->wikiId); $import = WikiEntityImport::findOrFail($this->importId); - $creds = $this->acquireCredentials($wiki->domain, $mwHostResolver); + $creds = self::acquireCredentials($wiki->domain, $mwHostResolver); - $this->targetWikiUrl = $this->domainToOrigin($wiki->domain); + $this->targetWikiUrl = self::domainToOrigin($wiki->domain); $kubernetesJob = new TransferBotKubernetesJob( kubernetesClient: $kubernetesClient, @@ -115,11 +115,11 @@ public function __construct( $this->transferbotImageVersion = Config::get('wbstack.transferbot_image_version'); } - private string $kubernetesNamespace; + private readonly string $kubernetesNamespace; - private string $transferbotImageRepo; + private readonly string $transferbotImageRepo; - private string $transferbotImageVersion; + private readonly string $transferbotImageVersion; public function spawn(): string { $spec = $this->constructSpec(); diff --git a/app/Notifications/ComplaintNotification.php b/app/Notifications/ComplaintNotification.php index 81462559..471d6f29 100644 --- a/app/Notifications/ComplaintNotification.php +++ b/app/Notifications/ComplaintNotification.php @@ -11,14 +11,6 @@ * A notification to be sent when the legal complaint form is being used. */ class ComplaintNotification extends Notification { - public $offendingUrls; - - public $reason; - - public $name; - - public $mailAddress; - /** * Create a notification instance. * @@ -28,11 +20,8 @@ class ComplaintNotification extends Notification { * @param string $mailAddress * @return void */ - public function __construct($offendingUrls, $reason, $name = null, $mailAddress = null) { - $this->offendingUrls = $offendingUrls; - $this->reason = $reason; - $this->name = $name; - $this->mailAddress = $mailAddress; + public function __construct(public $offendingUrls, public $reason, public $name = null, public $mailAddress = null) + { } /** diff --git a/app/Notifications/ComplaintNotificationExternal.php b/app/Notifications/ComplaintNotificationExternal.php index 220046fe..d07e2b6c 100644 --- a/app/Notifications/ComplaintNotificationExternal.php +++ b/app/Notifications/ComplaintNotificationExternal.php @@ -15,6 +15,7 @@ class ComplaintNotificationExternal extends ComplaintNotification { * @param mixed $notifiable * @return MailMessage */ + #[\Override] public function toMail($notifiable) { $name = $this->name; diff --git a/app/Notifications/ContactNotification.php b/app/Notifications/ContactNotification.php index e3a8d570..f5376ec8 100644 --- a/app/Notifications/ContactNotification.php +++ b/app/Notifications/ContactNotification.php @@ -10,14 +10,6 @@ * A notification to be sent when the contact form is being used. */ class ContactNotification extends Notification { - public $name; - - public $subject; - - public $message; - - public $contactDetails; - /** * Create a notification instance. * @@ -27,11 +19,8 @@ class ContactNotification extends Notification { * @param string $contactDetails * @return void */ - public function __construct($name, $subject, $message, $contactDetails = '') { - $this->name = $name; - $this->message = $message; - $this->subject = $subject; - $this->contactDetails = $contactDetails; + public function __construct(public $name, public $subject, public $message, public $contactDetails = '') + { } /** @@ -52,7 +41,7 @@ public function via($notifiable) { */ public function toMail($notifiable) { $subject = Lang::get('contact.' . $this->subject); - $contactDetails = $this->contactDetails ? $this->contactDetails : 'None'; + $contactDetails = $this->contactDetails ?: 'None'; $mailFrom = str_replace('', $this->subject, config('app.contact-mail-sender')); $mailSubject = config('app.name') . Lang::get(' contact form message: ') . $subject; diff --git a/app/Notifications/EmailReverificationNotification.php b/app/Notifications/EmailReverificationNotification.php index ef7b7b74..5c9db690 100644 --- a/app/Notifications/EmailReverificationNotification.php +++ b/app/Notifications/EmailReverificationNotification.php @@ -11,13 +11,6 @@ * and a new link is needed by the user. */ class EmailReverificationNotification extends Notification { - /** - * The email verification token. - * - * @var string - */ - public $token; - /** * The callback that should be used to build the mail message. * @@ -31,8 +24,13 @@ class EmailReverificationNotification extends Notification { * @param string $token * @return void */ - public function __construct($token) { - $this->token = $token; + public function __construct( + /** + * The email verification token. + */ + public $token + ) + { } /** diff --git a/app/Notifications/EmptyWikiNotification.php b/app/Notifications/EmptyWikiNotification.php index 93cbc01e..cc4db277 100644 --- a/app/Notifications/EmptyWikiNotification.php +++ b/app/Notifications/EmptyWikiNotification.php @@ -14,15 +14,13 @@ class EmptyWikiNotification extends Notification { const TYPE = 'empty_wiki_notification'; - private string $sitename; - /** * Create a notification instance. * * @return void */ - public function __construct(string $sitename) { - $this->sitename = $sitename; + public function __construct(private readonly string $sitename) + { } /** diff --git a/app/Notifications/ResetPasswordNotification.php b/app/Notifications/ResetPasswordNotification.php index 448f9e52..196d1101 100644 --- a/app/Notifications/ResetPasswordNotification.php +++ b/app/Notifications/ResetPasswordNotification.php @@ -10,13 +10,6 @@ class ResetPasswordNotification extends Notification { use HasFactory; - /** - * The password reset token. - * - * @var string - */ - public $token; - /** * The callback that should be used to build the mail message. * @@ -30,8 +23,13 @@ class ResetPasswordNotification extends Notification { * @param string $token * @return void */ - public function __construct($token) { - $this->token = $token; + public function __construct( + /** + * The password reset token. + */ + public $token + ) + { } /** @@ -55,7 +53,7 @@ public function toMail($notifiable) { return call_user_func(static::$toMailCallback, $notifiable, $this->token); } - $encodedEmail = urlencode($notifiable->getEmailForPasswordReset()); + $encodedEmail = urlencode((string) $notifiable->getEmailForPasswordReset()); $queryPart = "?token=$this->token&email={$encodedEmail}"; $resetPasswordLink = config('wbstack.ui_url') . '/reset-password' . $queryPart; diff --git a/app/Notifications/UserCreationNotification.php b/app/Notifications/UserCreationNotification.php index efd66f63..161c4c30 100644 --- a/app/Notifications/UserCreationNotification.php +++ b/app/Notifications/UserCreationNotification.php @@ -10,13 +10,6 @@ * Notification to be sent after account creation that includes a verification link. */ class UserCreationNotification extends Notification { - /** - * The email verification token. - * - * @var string - */ - public $token; - /** * The callback that should be used to build the mail message. * @@ -30,8 +23,13 @@ class UserCreationNotification extends Notification { * @param string $token * @return void */ - public function __construct($token) { - $this->token = $token; + public function __construct( + /** + * The email verification token. + */ + public $token + ) + { } /** diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 38f07d75..1aee7fb7 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -12,6 +12,7 @@ class AppServiceProvider extends ServiceProvider { /** * Register any application services. */ + #[\Override] public function register(): void { $this->app->bind(HttpRequest::class, CurlRequest::class); } diff --git a/app/Providers/CollectorRegistryProvider.php b/app/Providers/CollectorRegistryProvider.php index ebc36f6e..c3f2991f 100644 --- a/app/Providers/CollectorRegistryProvider.php +++ b/app/Providers/CollectorRegistryProvider.php @@ -13,17 +13,16 @@ class CollectorRegistryProvider extends ServiceProvider { /** * Register services. */ + #[\Override] public function register(): void { - $this->app->bind(CollectorRegistry::class, function (Application $app) { - return new CollectorRegistry(new Redis([ - 'host' => Config::get('database.redis.metrics.host'), - 'port' => Config::get('database.redis.metrics.port'), - 'password' => Config::get('database.redis.metrics.password'), - 'timeout' => 0.1, // in seconds - 'read_timeout' => '10', // in seconds - 'persistent_connections' => false, - ])); - }, true); + $this->app->bind(CollectorRegistry::class, fn(Application $app) => new CollectorRegistry(new Redis([ + 'host' => Config::get('database.redis.metrics.host'), + 'port' => Config::get('database.redis.metrics.port'), + 'password' => Config::get('database.redis.metrics.password'), + 'timeout' => 0.1, // in seconds + 'read_timeout' => '10', // in seconds + 'persistent_connections' => false, + ])), true); } /** diff --git a/app/Providers/DomainValidatorServiceProvider.php b/app/Providers/DomainValidatorServiceProvider.php index 4af0c012..6918cd6a 100644 --- a/app/Providers/DomainValidatorServiceProvider.php +++ b/app/Providers/DomainValidatorServiceProvider.php @@ -13,6 +13,7 @@ class DomainValidatorServiceProvider extends ServiceProvider { * * @return void */ + #[\Override] public function register() { $this->app->singleton(DomainValidator::class, function ($app) { $suffix = Config::get('wbstack.subdomain_suffix'); diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index a14d3f96..75032313 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -21,6 +21,7 @@ class EventServiceProvider extends ServiceProvider { /** * Register any events for your application. */ + #[\Override] public function boot(): void { parent::boot(); @@ -30,6 +31,7 @@ public function boot(): void { /** * Determine if events and listeners should be automatically discovered. */ + #[\Override] public function shouldDiscoverEvents(): bool { return false; } diff --git a/app/Providers/HorizonServiceProvider.php b/app/Providers/HorizonServiceProvider.php index e185692e..49995bb4 100644 --- a/app/Providers/HorizonServiceProvider.php +++ b/app/Providers/HorizonServiceProvider.php @@ -10,6 +10,7 @@ class HorizonServiceProvider extends HorizonApplicationServiceProvider { /** * Bootstrap any application services. */ + #[\Override] public function boot(): void { parent::boot(); @@ -23,11 +24,10 @@ public function boot(): void { * * This gate determines who can access Horizon in non-local environments. */ + #[\Override] protected function gate(): void { - Gate::define('viewHorizon', function ($user) { - return in_array($user->email, [ - // - ]); - }); + Gate::define('viewHorizon', fn($user) => in_array($user->email, [ + // + ])); } } diff --git a/app/Providers/KubernetesClientServiceProvider.php b/app/Providers/KubernetesClientServiceProvider.php index 73723e6d..a3bf657a 100644 --- a/app/Providers/KubernetesClientServiceProvider.php +++ b/app/Providers/KubernetesClientServiceProvider.php @@ -12,6 +12,7 @@ class KubernetesClientServiceProvider extends ServiceProvider { * * @return void */ + #[\Override] public function register() { $this->app->bind(Client::class, function ($app) { $httpClient = GuzzleClient::createWithConfig([ diff --git a/app/Providers/ReCaptchaServiceProvider.php b/app/Providers/ReCaptchaServiceProvider.php index 84215414..00860878 100644 --- a/app/Providers/ReCaptchaServiceProvider.php +++ b/app/Providers/ReCaptchaServiceProvider.php @@ -12,6 +12,7 @@ class ReCaptchaServiceProvider extends ServiceProvider { * * @return void */ + #[\Override] public function register() { $this->app->bind(ReCaptchaValidation::class, function ($app) { $recaptcha = new ReCaptcha( @@ -31,6 +32,7 @@ public function register() { * * @return array */ + #[\Override] public function provides() { return [ReCaptchaValidation::class]; } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index fa8d9f43..eb0750f4 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -18,6 +18,7 @@ class RouteServiceProvider extends ServiceProvider { /** * Define your route model bindings, pattern filters, etc. */ + #[\Override] public function boot(): void { // diff --git a/app/QsBatch.php b/app/QsBatch.php index 81491d12..24e7ffd7 100644 --- a/app/QsBatch.php +++ b/app/QsBatch.php @@ -48,6 +48,7 @@ public function wiki(): BelongsTo { return $this->belongsTo(Wiki::class); } + #[\Override] protected function casts(): array { return [ 'pending_since' => 'datetime', diff --git a/app/Rules/ForbiddenSubdomainRule.php b/app/Rules/ForbiddenSubdomainRule.php index c7df427f..04ce9034 100644 --- a/app/Rules/ForbiddenSubdomainRule.php +++ b/app/Rules/ForbiddenSubdomainRule.php @@ -5,10 +5,6 @@ use Illuminate\Contracts\Validation\Rule; class ForbiddenSubdomainRule implements Rule { - private $badWords; - - private $subdomainSuffix; - const ERROR_MESSAGE = 'The subdomain contains a forbidden word.'; /** @@ -16,9 +12,8 @@ class ForbiddenSubdomainRule implements Rule { * * @return void */ - public function __construct(array $badWords, string $subdomainSuffix) { - $this->badWords = $badWords; - $this->subdomainSuffix = $subdomainSuffix; + public function __construct(private readonly array $badWords, private readonly string $subdomainSuffix) + { } /** @@ -31,7 +26,7 @@ public function __construct(array $badWords, string $subdomainSuffix) { public function passes($attribute, $value) { $matches = []; $regexp = '/^([a-z0-9-]+)' . preg_quote($this->subdomainSuffix) . '$/'; - preg_match($regexp, $value, $matches, PREG_OFFSET_CAPTURE); + preg_match($regexp, (string) $value, $matches, PREG_OFFSET_CAPTURE); if (count($matches) !== 2) { return false; diff --git a/app/Rules/NonEmptyJsonRule.php b/app/Rules/NonEmptyJsonRule.php index bc341a80..2ec8ec7a 100644 --- a/app/Rules/NonEmptyJsonRule.php +++ b/app/Rules/NonEmptyJsonRule.php @@ -7,7 +7,7 @@ class NonEmptyJsonRule implements ValidationRule { public function validate(string $attribute, mixed $value, Closure $fail): void { - $json = json_decode($value, true); + $json = json_decode((string) $value, true); if (!is_array($json) || empty($json)) { $fail("The {$attribute} field must be a non-empty JSON object."); } diff --git a/app/Rules/ReCaptchaValidation.php b/app/Rules/ReCaptchaValidation.php index b26437a7..e55f3a70 100644 --- a/app/Rules/ReCaptchaValidation.php +++ b/app/Rules/ReCaptchaValidation.php @@ -15,19 +15,17 @@ class ReCaptchaValidation implements ImplicitRule { protected $recaptcha; /** + * @param string $minScore + * @param string $appUrl + */ + public function __construct(ReCaptcha $recaptcha, /** * @var string Lowest score to pass (0.0 - 1.0) */ - protected $minScore; - - /** + protected $minScore, /** * @var string App URL of client request */ - protected $appUrl; - - public function __construct(ReCaptcha $recaptcha, $minScore, $appUrl) { + protected $appUrl) { $this->recaptcha = $recaptcha; - $this->minScore = $minScore; - $this->appUrl = $appUrl; } /** diff --git a/app/Rules/SettingCaptchaQuestions.php b/app/Rules/SettingCaptchaQuestions.php index d5bc7c87..3caef56c 100644 --- a/app/Rules/SettingCaptchaQuestions.php +++ b/app/Rules/SettingCaptchaQuestions.php @@ -13,7 +13,7 @@ class SettingCaptchaQuestions implements Rule { * @return bool */ public function passes($attribute, $value) { - $value = json_decode($value, true); + $value = json_decode((string) $value, true); if ($value === null) { return false; diff --git a/app/Rules/SettingWikibaseManifestEquivEntities.php b/app/Rules/SettingWikibaseManifestEquivEntities.php index 3508ba1d..465b95e9 100644 --- a/app/Rules/SettingWikibaseManifestEquivEntities.php +++ b/app/Rules/SettingWikibaseManifestEquivEntities.php @@ -20,7 +20,7 @@ class SettingWikibaseManifestEquivEntities implements Rule { * @return bool */ public function passes($attribute, $value) { - $value = json_decode($value, true); + $value = json_decode((string) $value, true); if ($value === null) { return false; @@ -35,7 +35,7 @@ public function passes($attribute, $value) { foreach ($value[$entityType] as $local => $wikidata) { // Make sure that we have a single array mapping some property to some value - if (!preg_match($validationRule, $local) || !is_string($wikidata) || !preg_match($validationRule, $wikidata)) { + if (!preg_match($validationRule, (string) $local) || !is_string($wikidata) || !preg_match($validationRule, $wikidata)) { return false; } } diff --git a/app/Services/WikiUserEmailChecker.php b/app/Services/WikiUserEmailChecker.php index 6a653578..2043ec06 100644 --- a/app/Services/WikiUserEmailChecker.php +++ b/app/Services/WikiUserEmailChecker.php @@ -6,7 +6,7 @@ use PDO; class WikiUserEmailChecker { - public function __construct(private DatabaseManager $db) {} + public function __construct(private readonly DatabaseManager $db) {} public function findEmail(string $email): array { $this->db->purge('mw'); diff --git a/app/TermsOfUseVersion.php b/app/TermsOfUseVersion.php index 9c48f25b..8c7aaa18 100644 --- a/app/TermsOfUseVersion.php +++ b/app/TermsOfUseVersion.php @@ -28,6 +28,7 @@ public static function latestActiveVersion(): ?self { return self::query()->where('active', true)->latest()->first(); } + #[\Override] protected function casts(): array { return [ 'version' => 'string', diff --git a/app/Traits/PageFetcher.php b/app/Traits/PageFetcher.php index 09bc04e9..6b615ded 100644 --- a/app/Traits/PageFetcher.php +++ b/app/Traits/PageFetcher.php @@ -46,9 +46,7 @@ public function fetchPagesInNamespace(string $wikiDomain, MediawikiNamespace $na } $pages = data_get($jsonResponse, 'query.allpages', []); - $titles = array_merge($titles, array_map(function (array $page) { - return $page['title']; - }, $pages)); + $titles = array_merge($titles, array_map(fn(array $page) => $page['title'], $pages)); $nextCursor = data_get($jsonResponse, 'continue.apcontinue'); if ($nextCursor === null) { diff --git a/app/User.php b/app/User.php index 96b1d0d0..702158ef 100644 --- a/app/User.php +++ b/app/User.php @@ -85,6 +85,7 @@ class User extends Authenticatable implements MustVerifyEmail { 'card_last_four', ]; + #[\Override] public function sendPasswordResetNotification($token) { $this->notify(new ResetPasswordNotification($token)); } @@ -97,16 +98,19 @@ public function touAcceptances(): HasMany { return $this->hasMany(UserTermsOfUseAcceptance::class, 'user_id'); } + #[\Override] public function hasVerifiedEmail() { return (bool) $this->verified; } + #[\Override] public function markEmailAsVerified() { $this->verified = 1; return true; } + #[\Override] public function sendEmailVerificationNotification() { // This is required by the MustVerifyEmail interface that we use for middle ware. // But we currently send our emails via a different means, so we havn't implemented this.. @@ -116,6 +120,7 @@ public function sendEmailVerificationNotification() { // throw new RuntimeException('Not yet implemented'); } + #[\Override] public function getEmailForVerification() { return $this->email; } @@ -125,6 +130,7 @@ public function getEmailForVerification() { * * @return array */ + #[\Override] protected function casts(): array { return [ 'email_verified_at' => 'datetime', diff --git a/app/UserTermsOfUseAcceptance.php b/app/UserTermsOfUseAcceptance.php index 38bf0882..6aa3e3db 100644 --- a/app/UserTermsOfUseAcceptance.php +++ b/app/UserTermsOfUseAcceptance.php @@ -25,6 +25,7 @@ public function user(): BelongsTo { return $this->belongsTo(User::class); } + #[\Override] protected function casts(): array { return [ 'tou_version' => 'string', diff --git a/app/Wiki.php b/app/Wiki.php index 2c89ff02..de641290 100644 --- a/app/Wiki.php +++ b/app/Wiki.php @@ -154,9 +154,7 @@ public static function getSiteDirectory(int $wiki_id): string { * Convert the IDN formatted domain name to it's Unicode representation. */ protected function domainDecoded(): Attribute { - return Attribute::make(get: function () { - return DomainHelper::decode($this->domain); - }); + return Attribute::make(get: fn() => DomainHelper::decode($this->domain)); } public function wikiLatestProfile() { @@ -174,6 +172,7 @@ public function deleteSetting(string $name): ?string { return $this->settings()->where('name', $name)->delete(); } + #[\Override] protected function casts(): array { return [ 'deleted_at' => 'datetime', diff --git a/app/WikiEntityImport.php b/app/WikiEntityImport.php index 63e812c3..44c1f8bf 100644 --- a/app/WikiEntityImport.php +++ b/app/WikiEntityImport.php @@ -19,6 +19,7 @@ class WikiEntityImport extends Model { protected $visible = self::FIELDS; + #[\Override] protected function casts(): array { return [ 'status' => WikiEntityImportStatus::class, diff --git a/app/WikiLifecycleEvents.php b/app/WikiLifecycleEvents.php index 4901db5d..64903061 100644 --- a/app/WikiLifecycleEvents.php +++ b/app/WikiLifecycleEvents.php @@ -20,6 +20,7 @@ class WikiLifecycleEvents extends Model { protected $visible = self::FIELDS; + #[\Override] protected function casts(): array { return [ 'first_edited' => 'datetime', diff --git a/app/WikiNotificationSentRecord.php b/app/WikiNotificationSentRecord.php index 03be2485..44aeb1eb 100644 --- a/app/WikiNotificationSentRecord.php +++ b/app/WikiNotificationSentRecord.php @@ -17,6 +17,7 @@ class WikiNotificationSentRecord extends Model { protected $visible = self::FIELDS; + #[\Override] protected function casts(): array { return [ 'notification_type' => 'string', diff --git a/config/horizon.php b/config/horizon.php index c08e12a0..83a0089d 100644 --- a/config/horizon.php +++ b/config/horizon.php @@ -182,7 +182,7 @@ 'defaults' => [ 'supervisor-1' => [ 'connection' => 'redis', - 'queue' => explode(',', env('QUEUE_NAMES', 'default')), + 'queue' => explode(',', (string) env('QUEUE_NAMES', 'default')), 'balance' => env('HORIZON_BALANCING_STRATEGY', 'auto'), 'autoScalingStrategy' => env('HORIZON_AUTO_SCALING_STRATEGY', 'time'), 'maxProcesses' => intval(env('HORIZON_MAX_PROCESSES', 1)), diff --git a/config/ide-helper.php b/config/ide-helper.php index 93bd0270..ffd4bd99 100644 --- a/config/ide-helper.php +++ b/config/ide-helper.php @@ -118,8 +118,8 @@ */ 'extra' => [ - 'Eloquent' => ['Illuminate\Database\Eloquent\Builder', 'Illuminate\Database\Query\Builder'], - 'Session' => ['Illuminate\Session\Store'], + 'Eloquent' => [\Illuminate\Database\Eloquent\Builder::class, \Illuminate\Database\Query\Builder::class], + 'Session' => [\Illuminate\Session\Store::class], ], 'magic' => [], diff --git a/config/queue.php b/config/queue.php index 359b97a4..40beacc8 100644 --- a/config/queue.php +++ b/config/queue.php @@ -100,5 +100,5 @@ 'table' => 'failed_jobs', ], - 'backoff' => explode(',', env('QUEUE_BACKOFF', '')), + 'backoff' => explode(',', (string) env('QUEUE_BACKOFF', '')), ]; diff --git a/config/trustedproxy.php b/config/trustedproxy.php index b32778be..104cfcd5 100644 --- a/config/trustedproxy.php +++ b/config/trustedproxy.php @@ -3,15 +3,12 @@ return [ 'proxies' => (function () { $split = array_filter( - explode(',', env('TRUSTED_PROXY_PROXIES', '')) + explode(',', (string) env('TRUSTED_PROXY_PROXIES', '')) ); - switch (count($split)) { - case 0: - return null; - case 1: - return $split[0]; - default: - return $split; - } + return match (count($split)) { + 0 => null, + 1 => $split[0], + default => $split, + }; })(), ]; diff --git a/config/wbstack.php b/config/wbstack.php index 76f4a2bb..7023efae 100644 --- a/config/wbstack.php +++ b/config/wbstack.php @@ -16,10 +16,10 @@ 'platform_summary_inactive_threshold' => env('WBSTACK_SUMMARY_INACTIVE_THRESHOLD', 60 * 60 * 24 * 90), 'platform_summary_creation_rate_ranges' => array_filter( - explode(',', env('WBSTACK_SUMMARY_CREATION_RATE_RANGES', '')) + explode(',', (string) env('WBSTACK_SUMMARY_CREATION_RATE_RANGES', '')) ), - 'elasticsearch_hosts' => array_filter(explode(',', env('ELASTICSEARCH_HOST', ''))), + 'elasticsearch_hosts' => array_filter(explode(',', (string) env('ELASTICSEARCH_HOST', ''))), 'elasticsearch_enabled_by_default' => env('WBSTACK_ELASTICSEARCH_ENABLED_BY_DEFAULT', false), 'elasticsearch_shared_index_prefix' => env('ELASTICSEARCH_SHARED_INDEX_PREFIX', null), diff --git a/resources/views/vendor/notifications/email.blade.php b/resources/views/vendor/notifications/email.blade.php index 80b2d4af..47aab17f 100644 --- a/resources/views/vendor/notifications/email.blade.php +++ b/resources/views/vendor/notifications/email.blade.php @@ -19,14 +19,10 @@ {{-- Action Button --}} @isset($actionText) $level, + default => 'primary', +}; ?> @component('mail::button', ['url' => $actionUrl, 'color' => $color]) {{ $actionText }} diff --git a/routes/general.php b/routes/general.php index 7457312c..8abc7a8a 100644 --- a/routes/general.php +++ b/routes/general.php @@ -12,7 +12,5 @@ // GET $router->get( 'healthz', - function () { - return 'It\'s Alive'; - } + fn() => 'It\'s Alive' ); diff --git a/tests/Commands/RebuildQueryserviceDataTest.php b/tests/Commands/RebuildQueryserviceDataTest.php index 07387a22..08497ce5 100644 --- a/tests/Commands/RebuildQueryserviceDataTest.php +++ b/tests/Commands/RebuildQueryserviceDataTest.php @@ -162,7 +162,7 @@ public function testWikiWithLexemes() { if ($job->wikiDomain !== 'rebuild.wikibase.cloud') { return false; } - if (count(explode(',', $job->entities)) !== 10) { + if (count(explode(',', (string) $job->entities)) !== 10) { return false; } if ($job->sparqlUrl !== 'http://queryservice.default.svc.cluster.local:9999/bigdata/namespace/test_ns_12345/sparql') { @@ -175,7 +175,7 @@ public function testWikiWithLexemes() { if ($job->wikiDomain !== 'rebuild.wikibase.cloud') { return false; } - if (count(explode(',', $job->entities)) !== 5) { + if (count(explode(',', (string) $job->entities)) !== 5) { return false; } if ($job->sparqlUrl !== 'http://queryservice.default.svc.cluster.local:9999/bigdata/namespace/test_ns_12345/sparql') { @@ -251,7 +251,7 @@ public function testWikiNoLexemes() { if ($job->wikiDomain !== 'rebuild.wikibase.cloud') { return false; } - if (count(explode(',', $job->entities)) !== 8) { + if (count(explode(',', (string) $job->entities)) !== 8) { return false; } if ($job->sparqlUrl !== 'http://queryservice.default.svc.cluster.local:9999/bigdata/namespace/test_ns_12345/sparql') { diff --git a/tests/Jobs/CirrusSearch/QueueSearchIndexBatchesTest.php b/tests/Jobs/CirrusSearch/QueueSearchIndexBatchesTest.php index 1e7845c7..d75208c1 100644 --- a/tests/Jobs/CirrusSearch/QueueSearchIndexBatchesTest.php +++ b/tests/Jobs/CirrusSearch/QueueSearchIndexBatchesTest.php @@ -96,20 +96,14 @@ public function testSuccess() { $job->setJob($mockJob); $job->handle($request, $this->mockMwHostResolver); - Queue::assertPushed(function (ForceSearchIndex $job) { - return $job->wikiId() === $this->wiki->id - && $job->fromId() === 0 && $job->toId() === 1000; - }); - - Queue::assertPushed(function (ForceSearchIndex $job) { - return $job->wikiId() === $this->wiki->id - && $job->fromId() === 1001 && $job->toId() === 1234; - }); - - Queue::assertPushed(function (ForceSearchIndex $job) { - return $job->wikiId() === $this->wiki->id - && $job->fromId() === 1235 && $job->toId() === 1236; - }); + Queue::assertPushed(fn(ForceSearchIndex $job) => $job->wikiId() === $this->wiki->id + && $job->fromId() === 0 && $job->toId() === 1000); + + Queue::assertPushed(fn(ForceSearchIndex $job) => $job->wikiId() === $this->wiki->id + && $job->fromId() === 1001 && $job->toId() === 1234); + + Queue::assertPushed(fn(ForceSearchIndex $job) => $job->wikiId() === $this->wiki->id + && $job->fromId() === 1235 && $job->toId() === 1236); } diff --git a/tests/Jobs/DeleteWikiJobTest.php b/tests/Jobs/DeleteWikiJobTest.php index d9943bd1..d40fb464 100644 --- a/tests/Jobs/DeleteWikiJobTest.php +++ b/tests/Jobs/DeleteWikiJobTest.php @@ -55,7 +55,7 @@ public function testDispatching() { $job->handle($this->app->make('db')); } - public function testDeletesWiki() { + public function testDeletesWiki(): never { $this->markTestSkipped('Pollutes the deleted wiki list'); // This is harder to resolve // because the setup is guaranteed to end the // transaction that refresh database has started ue to the DROP statement diff --git a/tests/Jobs/PlatformStatsSummaryJobTest.php b/tests/Jobs/PlatformStatsSummaryJobTest.php index 4a954200..4a9e8830 100644 --- a/tests/Jobs/PlatformStatsSummaryJobTest.php +++ b/tests/Jobs/PlatformStatsSummaryJobTest.php @@ -69,7 +69,7 @@ private function seedWikis() { WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $job = new ProvisionWikiDbJob($this->db_prefix . $n, $this->db_name . $n, null); - $job->handle($manager, $this->mockMwHostResolver); + $job->handle($manager); $wikiDb = WikiDb::whereName($this->db_name . $n)->first(); $wikiDb->update(['wiki_id' => $wiki->id]); @@ -80,7 +80,7 @@ private function seedWikis() { } - public function testQueryGetsStats() { + public function testQueryGetsStats(): never { $this->markTestSkipped('Pollutes the deleted wiki list'); Http::fake(); $this->seedWikis(); @@ -234,7 +234,7 @@ public function testGroupings() { ); } - public function testCreationStats() { + public function testCreationStats(): never { $this->markTestSkipped('Pollutes the deleted wiki list'); $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never())->method('fail'); diff --git a/tests/Jobs/SetWikiLogoTest.php b/tests/Jobs/SetWikiLogoTest.php index 520052a1..d2bd9c95 100644 --- a/tests/Jobs/SetWikiLogoTest.php +++ b/tests/Jobs/SetWikiLogoTest.php @@ -65,13 +65,13 @@ public function testSetLogoSucceeds($wikiKey, $wikiValue, $logoPath) { // get the previous logo and favicon settings try { - $previousLogoSettingURL = parse_url($wiki->settings()->firstWhere(['name' => WikiSetting::wgLogo])->value); + $previousLogoSettingURL = parse_url((string) $wiki->settings()->firstWhere(['name' => WikiSetting::wgLogo])->value); } catch (ErrorException $e) { $previousLogoSettingURL = null; } try { - $previousFaviconSettingURL = parse_url($wiki->settings()->firstWhere(['name' => WikiSetting::wgFavicon])->value); - } catch (ErrorException $e) { + $previousFaviconSettingURL = parse_url((string) $wiki->settings()->firstWhere(['name' => WikiSetting::wgFavicon])->value); + } catch (ErrorException) { $previousFaviconSettingURL = null; } @@ -90,8 +90,8 @@ public function testSetLogoSucceeds($wikiKey, $wikiValue, $logoPath) { $this->assertSame(64, $logo->width()); // get the current logo and favicon settings - $currentLogoSettingURL = parse_url($wiki->settings()->firstWhere(['name' => WikiSetting::wgLogo])->value); - $currentFaviconSettingURL = parse_url($wiki->settings()->firstWhere(['name' => WikiSetting::wgFavicon])->value); + $currentLogoSettingURL = parse_url((string) $wiki->settings()->firstWhere(['name' => WikiSetting::wgLogo])->value); + $currentFaviconSettingURL = parse_url((string) $wiki->settings()->firstWhere(['name' => WikiSetting::wgFavicon])->value); // check the settings have been updated $this->assertNotEquals($previousLogoSettingURL, $currentLogoSettingURL); diff --git a/tests/Jobs/UpdateQueryserviceAllowListTest.php b/tests/Jobs/UpdateQueryserviceAllowListTest.php index cbc6a46e..686e03a2 100644 --- a/tests/Jobs/UpdateQueryserviceAllowListTest.php +++ b/tests/Jobs/UpdateQueryserviceAllowListTest.php @@ -107,7 +107,7 @@ public function testSuccess(): void { ]), ], ], - json_decode($requests[1]['request']->getBody(), true) + json_decode((string) $requests[1]['request']->getBody(), true) ); } } diff --git a/tests/Jobs/UserTermsOfUseAcceptanceTest.php b/tests/Jobs/UserTermsOfUseAcceptanceTest.php index ddbf70ec..8c9969e5 100644 --- a/tests/Jobs/UserTermsOfUseAcceptanceTest.php +++ b/tests/Jobs/UserTermsOfUseAcceptanceTest.php @@ -15,7 +15,7 @@ class UserTermsOfUseAcceptanceTest extends TestCase { public function testUserCreationCreatesTouAcceptance(): void { (new CreateFirstTermsOfUseVersionJob)->handle(); $email = 'test+' . uniqid('', true) . '@example.com'; - $user = (new UserCreateJob($email, 'thisisapassword123', true))->handle(); + $user = new UserCreateJob($email, 'thisisapassword123', true)->handle(); $this->assertDatabaseHas('tou_acceptances', [ 'user_id' => $user->id, diff --git a/tests/Middleware/AuthenticateTest.php b/tests/Middleware/AuthenticateTest.php index 567a98f7..14231458 100644 --- a/tests/Middleware/AuthenticateTest.php +++ b/tests/Middleware/AuthenticateTest.php @@ -13,7 +13,7 @@ class AuthenticateTest extends TestCase { use RefreshDatabase; - private const ENDPOINT = '/api/test/authenticate-middleware'; + private const string ENDPOINT = '/api/test/authenticate-middleware'; protected function setUp(): void { parent::setUp(); @@ -21,11 +21,9 @@ protected function setUp(): void { Artisan::call('passport:install', ['--no-interaction' => true]); // Register new test route with Authenticate middleware. This also tests the config in Kernel.php and auth.php. - Route::middleware('auth:api')->get(self::ENDPOINT, function (Request $request) { - return response()->json([ - 'email' => $request->user()->email, - ]); - }); + Route::middleware('auth:api')->get(self::ENDPOINT, fn(Request $request) => response()->json([ + 'email' => $request->user()->email, + ])); } public function testReturnsCustomJsonWhenUnauthenticated(): void { diff --git a/tests/Middleware/LimitWikiAccessTest.php b/tests/Middleware/LimitWikiAccessTest.php index 7d6cd7dc..f901f6b5 100644 --- a/tests/Middleware/LimitWikiAccessTest.php +++ b/tests/Middleware/LimitWikiAccessTest.php @@ -15,11 +15,9 @@ class LimitWikiAccessTest extends TestCase { protected function setUp(): void { parent::setUp(); - Route::middleware('limit_wiki_access')->get('/endpoint', function (Request $request) { - return response()->json([ - 'wiki_id' => $request->attributes->get('wiki')->id, - ]); - }); + Route::middleware('limit_wiki_access')->get('/endpoint', fn(Request $request) => response()->json([ + 'wiki_id' => $request->attributes->get('wiki')->id, + ])); } protected function tearDown(): void { diff --git a/tests/Routes/Complaint/SendMessageTest.php b/tests/Routes/Complaint/SendMessageTest.php index d26acda5..6609a7db 100644 --- a/tests/Routes/Complaint/SendMessageTest.php +++ b/tests/Routes/Complaint/SendMessageTest.php @@ -70,7 +70,7 @@ public function testRecordOnMailFail() { try { $response = $this->json('POST', $this->route, $data); - } catch (TransportException $e) { + } catch (TransportException) { return; } diff --git a/tests/Routes/User/ForgotPasswordTest.php b/tests/Routes/User/ForgotPasswordTest.php index 0e8d5d9d..3dca5638 100644 --- a/tests/Routes/User/ForgotPasswordTest.php +++ b/tests/Routes/User/ForgotPasswordTest.php @@ -22,9 +22,7 @@ public function testForgotPasswordSubmissionSuccess() { ->assertStatus(200); Notification::assertSentTo( $user, - function (ResetPasswordNotification $notification) use ($user) { - return str_contains($notification->toMail($user)->data()['actionUrl'], 'foo%2Bbar%40example.com'); - } + fn(ResetPasswordNotification $notification) => str_contains((string) $notification->toMail($user)->data()['actionUrl'], 'foo%2Bbar%40example.com') ); } diff --git a/tests/Routes/Wiki/DeletedWikiMetricsControllerTest.php b/tests/Routes/Wiki/DeletedWikiMetricsControllerTest.php index 28551858..4096f3f8 100644 --- a/tests/Routes/Wiki/DeletedWikiMetricsControllerTest.php +++ b/tests/Routes/Wiki/DeletedWikiMetricsControllerTest.php @@ -72,7 +72,7 @@ public function testOutputHasCorrectContent() { $response = $this->get($this->route); $rawCsv = $response->getContent(); - $output = array_map('str_getcsv', explode("\n", $rawCsv)); + $output = array_map(str_getcsv(...), explode("\n", $rawCsv)); $this->assertSame('one.wikibase.cloud', $output[1][0]); $this->assertSame('two.wikibase.cloud', $output[2][0]); $this->assertSame('Some Reason', $output[2][1]); diff --git a/tests/TestCase.php b/tests/TestCase.php index d5f0b7da..612ee075 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -12,6 +12,7 @@ abstract class TestCase extends BaseTestCase { * * @return Application */ + #[\Override] public function createApplication() { putenv('QUEUE_CONNECTION=sync'); $app = require __DIR__ . '/../bootstrap/app.php'; From 8e40160d8ec8bc85f652f52593339dc9ed892386 Mon Sep 17 00:00:00 2001 From: dena Date: Tue, 19 May 2026 16:42:41 +0200 Subject: [PATCH 8/8] fix domain handling --- app/Helper/DomainHelper.php | 16 ++++++---------- app/Http/Controllers/WikiController.php | 1 + 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/app/Helper/DomainHelper.php b/app/Helper/DomainHelper.php index 24305a52..0097f438 100644 --- a/app/Helper/DomainHelper.php +++ b/app/Helper/DomainHelper.php @@ -17,11 +17,9 @@ class DomainHelper { // @return string - the domain name encoded in ASCII-compatible form public static function encode($string) { - $result = idn_to_ascii($string); - - // return the original input if encoding failed - if ($result === false) { - $result = $string; + $result = $string; + if (!empty($string)) { + $result = idn_to_ascii($string); } return $result; @@ -29,11 +27,9 @@ public static function encode($string) { // @return string - the domain name in Unicode, encoded in UTF-8 public static function decode($string) { - $result = idn_to_utf8($string); - - // return the original input if decoding failed - if ($result === false) { - $result = $string; + $result = $string; + if (!empty($string)) { + $result = idn_to_utf8($string); } return $result; diff --git a/app/Http/Controllers/WikiController.php b/app/Http/Controllers/WikiController.php index b744d1ef..d7555ee9 100644 --- a/app/Http/Controllers/WikiController.php +++ b/app/Http/Controllers/WikiController.php @@ -51,6 +51,7 @@ public function create(Request $request): Response { // TODO extra validation that username is correct? $request->validate([ + 'domain' => 'required', 'sitename' => 'required|min:3', 'username' => 'required', 'profile' => 'nullable|json',