From 80f56a8b983cec27e2875e5829ef72b0127fce10 Mon Sep 17 00:00:00 2001 From: Brian Foley Date: Tue, 20 Oct 2026 22:58:51 +0100 Subject: [PATCH 1/6] html_page_common.inc: Fix output_html_header only-once guard Found by PHPStan 2.3 --- pinc/html_page_common.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/pinc/html_page_common.inc b/pinc/html_page_common.inc index 54cb87c15..4bd61d843 100644 --- a/pinc/html_page_common.inc +++ b/pinc/html_page_common.inc @@ -23,6 +23,7 @@ function output_html_header(?string $nameofpage, array $extra_args = [], bool $s if ($was_output) { return; } + $was_output = true; $user = User::load_current(); From 04fa52fc9104f2ae512c24cc42e7cb26bf1adc2d Mon Sep 17 00:00:00 2001 From: Brian Foley Date: Tue, 20 Oct 2026 23:33:47 +0100 Subject: [PATCH 2/6] ap1/v1/queues endpoint: Add missing param invalidation Found by PHPStan 2.3 complaining about unused `$valid_fields` --- SETUP/tests/smoketests/pageload_smoketest.py | 3 +++ api/v1_queues.inc | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/SETUP/tests/smoketests/pageload_smoketest.py b/SETUP/tests/smoketests/pageload_smoketest.py index 4a4737603..c4260441e 100755 --- a/SETUP/tests/smoketests/pageload_smoketest.py +++ b/SETUP/tests/smoketests/pageload_smoketest.py @@ -76,6 +76,9 @@ {'name': 'api-queues', 'path': 'api/index.php?url=v1/queues'}, {'name': 'api-queue', 'path': 'api/index.php?url=v1/queues/500'}, + {'name': 'api-queue-noname', 'path': 'api/index.php?url=v1/queues&name=noname'}, + {'name': 'api-queue-inv-keys', 'path': 'api/index.php?url=v1/queues&invalid=query', 'expect_status': 400}, + {'name': 'api-queue-inv-field', 'path': 'api/index.php?url=v1/queues&field[]=name&field[]=enabled&field[]=place-des', 'expect_status': 400}, {'name': 'api-queue-stats', 'path': 'api/index.php?url=v1/queues/500/stats'}, {'name': 'api-queue-projects', 'path': 'api/index.php?url=v1/queues/500/projects'}, diff --git a/api/v1_queues.inc b/api/v1_queues.inc index c76c4607f..04602d272 100644 --- a/api/v1_queues.inc +++ b/api/v1_queues.inc @@ -43,9 +43,19 @@ function api_v1_queues(string $_method, array $_data, array $query_params): arra array_push($valid_return_fields, "project_selector", "projects_target", "pages_target"); } - // restrict to list of desired fields, if set $return_fields = array_get_as_array($query_params, "field", $valid_return_fields); - $return_fields = array_intersect($return_fields, $valid_return_fields); + + // Validate query params + $valid_query_keys = array_merge($valid_fields, ['show', 'field']); + $invalid_query_params = array_diff(array_keys($query_params), $valid_query_keys); + if (!empty($invalid_query_params)) { + throw new InvalidValue("Invalid query args: " . join(", ", $invalid_query_params)); + } + + $invalid_fields = array_diff($return_fields, $valid_return_fields); + if (!empty($invalid_fields)) { + throw new InvalidValue("Invalid field[] args: " . join(", ", $invalid_fields)); + } $name_selector = $query_params["name"] ?? null; $group_selector = $query_params["group"] ?? null; From 484b1aaa410d554b7adffd2826230a8c64c0d460 Mon Sep 17 00:00:00 2001 From: Brian Foley Date: Tue, 20 Oct 2026 23:04:21 +0100 Subject: [PATCH 3/6] bad_bytes.inc: Quell define_bad_byte_sequences PHPStan warnings PHPStan can't see that the global `_bad_byte_sequences` is mutated by `_install_bad_sequence` and thinks it's empty unless told otherwise --- pinc/bad_bytes.inc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pinc/bad_bytes.inc b/pinc/bad_bytes.inc index 0e55aee3e..1295a4467 100644 --- a/pinc/bad_bytes.inc +++ b/pinc/bad_bytes.inc @@ -641,6 +641,7 @@ function define_bad_byte_sequences(): void { global $_bad_byte_sequences, $_character_data; + /** @var non-empty-array $_bad_byte_sequences */ $_bad_byte_sequences = []; foreach ($_character_data as $code_point => $info) { @@ -681,8 +682,8 @@ function define_bad_byte_sequences(): void ksort($_bad_byte_sequences); - if (0) { /** @phpstan-ignore-line */ - foreach ($_bad_byte_sequences as $raw => $remarks) { /** @phpstan-ignore-line Fixed in https://github.com/phpstan/phpstan/issues/9403 */ + if (0) { // @phpstan-ignore if.alwaysFalse + foreach ($_bad_byte_sequences as $raw => $remarks) { [$code_point, $why_bad] = $remarks; echo sprintf( "%s: U+%04x %s\n", From d753d7be82ba944f1ba2336d948d729e07f3a01b Mon Sep 17 00:00:00 2001 From: Brian Foley Date: Tue, 20 Oct 2026 23:42:39 +0100 Subject: [PATCH 4/6] Activity.inc: Fix access criteria minima_table type hints The table is an associative array, not a list, and the scores are floats (because 'days since reg' is float). Found by PHPStan 2.3. --- pinc/Activity.inc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pinc/Activity.inc b/pinc/Activity.inc index 8071dcfd4..564c8a4a2 100644 --- a/pinc/Activity.inc +++ b/pinc/Activity.inc @@ -6,6 +6,7 @@ include_once($relPath.'User.inc'); // $ACCESS_CRITERIA are extended as activities are defined. +/** @var array $ACCESS_CRITERIA */ global $ACCESS_CRITERIA; $ACCESS_CRITERIA = [ 'days since reg' => _('Days since registration'), @@ -128,7 +129,7 @@ class UserAccess /** * @param bool $can_access * user can access this activity. - * @param list{string, int, int, bool}[] $minima_table + * @param array $minima_table * ( $criterion_str, $minimum, $user_score, $satisfied ) * @param ?('sat-unneeded'|'sat-granted'|'sat-available'|'sat-requested'|'sat-wait'|'sat-denied'|'unsat-granted'|'unsat-requested'|'unsat-ungranted'|'unsat-denied') $request_status * @param ?string $evaluation_criteria From 311131f54d3bce3222a7d3b69959582d8e8c6565 Mon Sep 17 00:00:00 2001 From: Brian Foley Date: Fri, 16 Oct 2026 13:40:59 +0100 Subject: [PATCH 5/6] phpstan.neon: Ignore unused func params starting with _. We will be able to remove this with PHPStan 2.3.2 --- phpstan.neon | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/phpstan.neon b/phpstan.neon index 35dba7059..b674af833 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -76,6 +76,12 @@ parameters: paths: - pinc/3rdparty/mediawiki/*.php + # Use $_foo as the naming convention for unused function params that + # we want to keep to satisfy some API. Silence PHPStan warnings when + # this happens. + - message: '#Function .* has an unused parameter \$_.*\.#' + + typeAliases: # TODO: data.y should be numeric list, but callers needs fixing GraphConfig: """ From e88a5744c4dcab8298ad8d8630d77330510c53cc Mon Sep 17 00:00:00 2001 From: Brian Foley Date: Thu, 8 Oct 2026 23:34:48 +0100 Subject: [PATCH 6/6] Update to PHPstan 2.3.1 -- now with unused variable warnings! --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 0cfdd28ab..5b0aef4cb 100644 --- a/composer.lock +++ b/composer.lock @@ -1451,11 +1451,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.2.9", + "version": "2.3.1", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/13d6b4f347bad222da436580c8304fa6f83e6bd0", - "reference": "13d6b4f347bad222da436580c8304fa6f83e6bd0", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/6155239b488e95d26d1ebd95c6b4bb294d7f09db", + "reference": "6155239b488e95d26d1ebd95c6b4bb294d7f09db", "shasum": "" }, "require": { @@ -1511,7 +1511,7 @@ "type": "github" } ], - "time": "2026-08-22T07:38:16+00:00" + "time": "2026-10-08T21:09:11+00:00" }, { "name": "phpunit/php-code-coverage",