deploy some stricter phpstan rules

This commit is contained in:
Spine
2025-07-11 09:38:56 +00:00
parent 773b262a83
commit cef1aa91db
21 changed files with 191 additions and 53 deletions

View File

@@ -260,9 +260,7 @@ class Forum extends BaseObject {
);
}
/**
* @deprecated
*/
#[\Deprecated]
public function threadCount(): int {
$toc = $this->tableOfContentsForum();
return $toc ? current($toc)['threadCount'] : 0;
@@ -283,9 +281,8 @@ class Forum extends BaseObject {
* - int 'LastPostAuthorID' User id of author of most recent post
* - int 'stickyCount' Number of sticky posts
* - int 'threadCount' Total number of threads in forum
*
* @deprecated
*/
#[\Deprecated]
public function tableOfContentsForum(int $page = 1): array {
$key = sprintf(self::CACHE_TOC_FORUM, $this->id);
$forumToc = null;

View File

@@ -13,7 +13,7 @@ class SingleSeeded extends \Gazelle\Json {
fn ($torrent) => [
'torrentId' => $torrent->id(),
'groupId' => $torrent->groupId(),
'artistInfo' => $this->artistPayload($torrent->group()),
'artistInfo' => static::artistPayload($torrent->group()),
'groupName' => $torrent->group()->name(),
'groupYear' => $torrent->group()->year(),
'downloadUrl' => "torrents.php?action=download&id={$torrent->id()}&torrent_pass={$this->user->announceKey()}",

View File

@@ -20,7 +20,7 @@ class Transcode extends \Gazelle\Json {
$payload[] = [
'torrentId' => $torrent->id(),
'groupId' => $tgroup->id(),
'artistInfo' => $this->artistPayload($torrent->group()),
'artistInfo' => static::artistPayload($torrent->group()),
'groupName' => $tgroup->name(),
'groupYear' => $tgroup->year(),
'downloadUrl' => "torrents.php?action=download&id={$torrent->id()}&torrent_pass={$this->announceKey}",

View File

@@ -11,7 +11,7 @@ class TGroup extends \Gazelle\Json {
public function tgroupPayload(): array {
$tgroup = $this->tgroup;
$musicInfo = $this->artistPayload($tgroup);
$musicInfo = static::artistPayload($tgroup);
return [
'wikiBody' => \Text::full_format($tgroup->description()),

View File

@@ -236,9 +236,9 @@ class Request extends \Gazelle\BaseManager {
i.log_score, i.need_log, i.need_cue, i.need_checksum,
i.artist_title_ts,
i.tag,
string_to_array(i.encoding_str::text, '|'),
string_to_array(i.format_str::text, '|'),
string_to_array(i.media_str::text, '|')
i.encoding_str,
i.format_str,
i.media_str
)
when matched then
update set
@@ -251,9 +251,9 @@ class Request extends \Gazelle\BaseManager {
log_score = i.log_score, need_log = i.need_log,
need_cue = i.need_cue, need_checksum = i.need_checksum,
artist_title_ts = i.artist_title_ts, tag = i.tag,
encoding_str = string_to_array(i.encoding_str::text, '|'),
format_str = string_to_array(i.format_str::text, '|'),
media_str = string_to_array(i.media_str::text, '|')
encoding_str = i.encoding_str,
format_str = i.format_str,
media_str = i.media_str
");
}
}

View File

@@ -176,8 +176,8 @@ class Request extends BaseObject implements CategoryHasArtist {
);
$info['logCue'] = new Request\LogCue(
needLogChecksum: (bool)$info['checksum'],
needCue: strpos($info['log_cue'], 'Cue') !== false,
needLog: strpos($info['log_cue'], 'Log') !== false,
needCue: str_contains($info['log_cue'], 'Cue'),
needLog: str_contains($info['log_cue'], 'Log'),
minScore: (int)preg_replace('/\D+/', '', $info['log_cue']),
);

View File

@@ -154,7 +154,7 @@ class Bookmark extends \Gazelle\BaseUser {
* Check if a request is bookmarked by a user
*/
public function isRequestBookmarked(Request $request): bool {
return in_array($request, $this->allBookmarks('request'));
return in_array($request->id, $this->allBookmarks('request'));
}
/**

View File

@@ -21,11 +21,11 @@ class UserLink extends \Gazelle\BaseUser {
}
public function groupId(\Gazelle\User $user): ?int {
$id = (int)self::$db->scalar("
$id = self::$db->scalar("
SELECT GroupID FROM users_dupes WHERE UserID = ?
", $user->id
);
return $id ? (int)$id : null;
return is_null($id) ? null : (int)$id;
}
public function info(): array {

View File

@@ -194,8 +194,8 @@ class MatchCandidate {
continue;
}
$end = $end ?? $start;
$otherEnd = $otherEnd ?? $otherStart;
$end ??= $start;
$otherEnd ??= $otherStart;
/* possible cases:
* any two dates are very close

View File

@@ -62,7 +62,7 @@ class Sphinxql extends mysqli {
global $Debug;
$Debug->mark("Connecting to Sphinx server $this->Ident");
for ($Attempt = 0; $Attempt < 3; $Attempt++) {
parent::__construct($this->Server, '', '', '', $this->Port, $this->Socket);
parent::__construct($this->Server, '', '', '', $this->Port, $this->Socket); /** @phpstan-ignore-line kittens were drowned for this */
if (!$this->connect_errno) {
$this->Connected = true;
break;

View File

@@ -15,7 +15,10 @@
"classmap": ["classes/"]
},
"config": {
"sort-packages": true
"sort-packages": true,
"allow-plugins": {
"phpstan/extension-installer": true
}
},
"require": {
"php": "^8.4",
@@ -43,10 +46,12 @@
"brianium/paratest": "^7.9",
"phpmd/phpmd": "@stable",
"phpstan/phpstan": "^2.1",
"phpstan/extension-installer": "^1.4",
"phpstan/phpstan-strict-rules": "^2.0",
"phpunit/phpcov": "^11",
"phpunit/php-code-coverage": "^12",
"phpunit/phpunit": "^12",
"rector/rector": "^2.0",
"rector/rector": "^2.1",
"squizlabs/php_codesniffer": "^3.12"
}
}

124
composer.lock generated
View File

@@ -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": "84254745c0f3ef05c1cec3c81b293d32",
"content-hash": "a1aca354806f57bc6c77d2d16bea3a75",
"packages": [
{
"name": "bacon/bacon-qr-code",
@@ -3787,6 +3787,54 @@
],
"time": "2023-12-11T08:22:20+00:00"
},
{
"name": "phpstan/extension-installer",
"version": "1.4.3",
"source": {
"type": "git",
"url": "https://github.com/phpstan/extension-installer.git",
"reference": "85e90b3942d06b2326fba0403ec24fe912372936"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/extension-installer/zipball/85e90b3942d06b2326fba0403ec24fe912372936",
"reference": "85e90b3942d06b2326fba0403ec24fe912372936",
"shasum": ""
},
"require": {
"composer-plugin-api": "^2.0",
"php": "^7.2 || ^8.0",
"phpstan/phpstan": "^1.9.0 || ^2.0"
},
"require-dev": {
"composer/composer": "^2.0",
"php-parallel-lint/php-parallel-lint": "^1.2.0",
"phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0"
},
"type": "composer-plugin",
"extra": {
"class": "PHPStan\\ExtensionInstaller\\Plugin"
},
"autoload": {
"psr-4": {
"PHPStan\\ExtensionInstaller\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Composer plugin for automatic installation of PHPStan extensions",
"keywords": [
"dev",
"static analysis"
],
"support": {
"issues": "https://github.com/phpstan/extension-installer/issues",
"source": "https://github.com/phpstan/extension-installer/tree/1.4.3"
},
"time": "2024-09-04T20:21:43+00:00"
},
{
"name": "phpstan/phpstan",
"version": "2.1.17",
@@ -3845,6 +3893,54 @@
],
"time": "2025-05-21T20:55:28+00:00"
},
{
"name": "phpstan/phpstan-strict-rules",
"version": "2.0.4",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan-strict-rules.git",
"reference": "3e139cbe67fafa3588e1dbe27ca50f31fdb6236a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/3e139cbe67fafa3588e1dbe27ca50f31fdb6236a",
"reference": "3e139cbe67fafa3588e1dbe27ca50f31fdb6236a",
"shasum": ""
},
"require": {
"php": "^7.4 || ^8.0",
"phpstan/phpstan": "^2.0.4"
},
"require-dev": {
"php-parallel-lint/php-parallel-lint": "^1.2",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpunit/phpunit": "^9.6"
},
"type": "phpstan-extension",
"extra": {
"phpstan": {
"includes": [
"rules.neon"
]
}
},
"autoload": {
"psr-4": {
"PHPStan\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Extra strict and opinionated rules for PHPStan",
"support": {
"issues": "https://github.com/phpstan/phpstan-strict-rules/issues",
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.4"
},
"time": "2025-03-18T11:42:40+00:00"
},
{
"name": "phpunit/php-code-coverage",
"version": "12.3.1",
@@ -4243,16 +4339,16 @@
},
{
"name": "phpunit/phpunit",
"version": "12.2.6",
"version": "12.2.7",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "638644c62a58f04974da115f98981c9b48564021"
"reference": "8b1348b254e5959acaf1539c6bd790515fb49414"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/638644c62a58f04974da115f98981c9b48564021",
"reference": "638644c62a58f04974da115f98981c9b48564021",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/8b1348b254e5959acaf1539c6bd790515fb49414",
"reference": "8b1348b254e5959acaf1539c6bd790515fb49414",
"shasum": ""
},
"require": {
@@ -4262,7 +4358,7 @@
"ext-mbstring": "*",
"ext-xml": "*",
"ext-xmlwriter": "*",
"myclabs/deep-copy": "^1.13.1",
"myclabs/deep-copy": "^1.13.3",
"phar-io/manifest": "^2.0.4",
"phar-io/version": "^3.2.1",
"php": ">=8.3",
@@ -4320,7 +4416,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/12.2.6"
"source": "https://github.com/sebastianbergmann/phpunit/tree/12.2.7"
},
"funding": [
{
@@ -4344,20 +4440,20 @@
"type": "tidelift"
}
],
"time": "2025-07-04T06:00:16+00:00"
"time": "2025-07-11T04:11:13+00:00"
},
{
"name": "rector/rector",
"version": "2.1.0",
"version": "2.1.1",
"source": {
"type": "git",
"url": "https://github.com/rectorphp/rector.git",
"reference": "d513dea45a94394b660e15c155d1fa27826f8e30"
"reference": "d0917c069bb0d9bb06ed111cf052510f609015a4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rectorphp/rector/zipball/d513dea45a94394b660e15c155d1fa27826f8e30",
"reference": "d513dea45a94394b660e15c155d1fa27826f8e30",
"url": "https://api.github.com/repos/rectorphp/rector/zipball/d0917c069bb0d9bb06ed111cf052510f609015a4",
"reference": "d0917c069bb0d9bb06ed111cf052510f609015a4",
"shasum": ""
},
"require": {
@@ -4396,7 +4492,7 @@
],
"support": {
"issues": "https://github.com/rectorphp/rector/issues",
"source": "https://github.com/rectorphp/rector/tree/2.1.0"
"source": "https://github.com/rectorphp/rector/tree/2.1.1"
},
"funding": [
{
@@ -4404,7 +4500,7 @@
"type": "github"
}
],
"time": "2025-06-24T20:26:57+00:00"
"time": "2025-07-10T11:31:31+00:00"
},
{
"name": "sebastian/cli-parser",

View File

@@ -549,7 +549,7 @@ function array_key_filter_and_map(string $prefix, array $list, bool $cast = true
if (!str_starts_with($k, $prefix)) {
continue;
}
$key = $cast ? (int)explode('-', (string)$k, 2)[1] : explode('-', (string)$k, 2)[1];
$key = $cast ? (int)explode('-', $k, 2)[1] : explode('-', $k, 2)[1];
$out[$key] = $v;
}
return $out;
@@ -831,7 +831,7 @@ function check_paranoia(string $Property, string|array $Paranoia, int $UserClass
function httpProxy(): ?string {
$proxy = getenv('HTTP_PROXY');
if ($proxy !== false) {
return (string)$proxy;
return $proxy;
} elseif (HTTP_PROXY != false) {
return HTTP_PROXY;
}

View File

@@ -12,18 +12,47 @@ parameters:
checkMissingCallableSignature: true
checkTooWideReturnTypesInProtectedAndPublicMethods: true
polluteScopeWithAlwaysIterableForeach: false
polluteScopeWithBlock: false
polluteScopeWithLoopInitialAssignments: false
rememberPossiblyImpureFunctionValues: true
reportAlwaysTrueInLastCondition: true
reportAnyTypeWideningInVarTag: true
reportMaybesInMethodSignatures: true
reportMaybesInPropertyPhpDocTypes: true
reportPossiblyNonexistentConstantArrayOffset: true
reportPossiblyNonexistentGeneralArrayOffset: true
reportStaticMethodSignatures: true
reportWrongPhpDocTypeInVarTag: true
strictRules:
booleansInConditions: false
booleansInLoopConditions: false
closureUsesThis: true
disallowedBacktick: true
disallowedEmpty: false
disallowedImplicitArrayCreation: false
disallowedLooseComparison: false
disallowedShortTernary: false
dynamicCallOnStaticMethod: true
illegalConstructorMethodCall: true
matchingInheritedMethodNames: true
noVariableVariables: false
numericOperandsInArithmeticOperators: false
overwriteVariablesWithLoop: false
requireParentConstructorCall: false
strictArrayFilter: false
strictFunctionCalls: false
switchConditionsMatchingType: true
uselessCast: true
errorFormat: table
bootstrapFiles:
- ../lib/config.php
scanFiles:
- ../lib/bootstrap.php
paths:
- ../lib/util.php
- ../app
@@ -32,8 +61,12 @@ parameters:
- ../misc
- ../tests
- ../sections
parallel:
maximumNumberOfProcesses: 1
jobSize: 20
maximumNumberOfProcesses: 12
minimumNumberOfJobsPerProcess: 2
dynamicConstantNames:
- AJAX
- BITCOIN_DONATION_XYZPUB
@@ -76,6 +109,14 @@ parameters:
ignoreErrors:
-
identifier: offsetAccess.notFound
-
identifier: staticMethod.dynamicCall
paths:
- ../tests/phpunit/*
-
message: '#^Cannot unset property \S+ because it might have hooks in a subclass\.$#'
reportUnmatched: false

View File

@@ -62,7 +62,7 @@ if (!empty($_POST['username']) && !empty($_POST['password'])) {
'useragent' => $context->useragent(),
]);
(new SessionCookie(SessionCookie::encode($user, $current['SessionID'])))
new SessionCookie(SessionCookie::encode($user, $current['SessionID']))
->emit((int)$login->persistent() * (time() + 60 * 60 * 24 * 90));
header("Location: index.php");
exit;

View File

@@ -14,12 +14,14 @@ if (!$Viewer->permitted('admin_site_debug')) {
$proc = [];
if (preg_match('/.*\/(.*)/', PHP_BINARY, $match, PREG_UNMATCHED_AS_NULL)) {
$binary = $match[1];
$ps = trim(`ps -C {$binary} -o pid --no-header`);
$pidList = explode("\n", $ps);
foreach ($pidList as $pid) {
$p = $Cache->get_value("php_$pid");
if ($p !== false) {
$proc[$pid] = $p;
$ps = shell_exec("ps -C {$binary} -o pid --no-header");
if ($ps !== false && !is_null($ps)) {
$pidList = explode("\n", trim($ps));
foreach ($pidList as $pid) {
$p = $Cache->get_value("php_$pid");
if ($p !== false) {
$proc[$pid] = $p;
}
}
}
}

View File

@@ -34,7 +34,7 @@ if ($_POST) {
echo $Twig->render('admin/rate-limiting.twig', [
'class_list' => new Manager\User()->classList(),
'priv_list' => new Manager\Privilege()->privilegeList(),
'priv_list' => new Manager\Privilege()::privilegeList(),
'rate_list' => $limiter->list(),
'viewer' => $Viewer,
]);

View File

@@ -8,7 +8,7 @@ use GazelleUnitTest\Helper;
class DnuTest extends TestCase {
protected User $user;
public function setup(): void {
public function setUp(): void {
$this->user = Helper::makeUser('dnu.' . randomString(10), 'dnu');
}

View File

@@ -613,7 +613,6 @@ class RequestTest extends TestCase {
$this->userList['admin'],
'phpunit request json',
);
$artistMan = new Manager\Artist();
$this->request->artistRole()->set(
[ARTIST_MAIN => ['phpunit req ' . randomString(6)]],
$this->userList['user'],

View File

@@ -125,7 +125,6 @@ class WikiTest extends TestCase {
public function testWikiAlias(): void {
$manager = new Manager\Wiki();
$title = 'phpunit title ' . randomString(6);
$alias = Wiki::normalizeAlias($title);
$article = $manager->create(
$title,
'wiki body',

View File

@@ -63,7 +63,6 @@ class UserAdvancedTest extends TestCase {
#[DataProvider('dataDate')]
public function testSearchUserDate(string $name, string $compare, string $expected): void {
$search = new Search\User('');
$this->assertEquals(
$expected,
new Search\User('')->date('f', $compare),