Skip to content

Commit 00cc309

Browse files
author
HugoFara
committed
chore(backend): fixing issues with psalm.
2 parents 4c252e9 + 4bae0d7 commit 00cc309

30 files changed

+85
-174
lines changed

psalm.xml

Lines changed: 1 addition & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,6 @@
2828
</errorLevel>
2929
</UndefinedGlobalVariable>
3030

31-
<!-- Views use $this from controller context when included -->
32-
<InvalidScope>
33-
<errorLevel type="suppress">
34-
<directory name="src/backend/Views" />
35-
</errorLevel>
36-
</InvalidScope>
37-
3831
<!-- Controllers pass variables to views, services have template vars -->
3932
<UnusedVariable>
4033
<errorLevel type="suppress">
@@ -50,16 +43,9 @@
5043
<directory name="src/backend/Controllers" />
5144
<directory name="src/backend/Services" />
5245
<directory name="src/backend/View" />
53-
<directory name="src/backend/Core" />
5446
</errorLevel>
5547
</PossiblyUnusedParam>
5648

57-
<UnusedParam>
58-
<errorLevel type="suppress">
59-
<directory name="src/backend/Controllers" />
60-
</errorLevel>
61-
</UnusedParam>
62-
6349
<!-- Public methods called via routing or kept for API completeness -->
6450
<PossiblyUnusedMethod>
6551
<errorLevel type="suppress">
@@ -71,22 +57,6 @@
7157
</errorLevel>
7258
</PossiblyUnusedMethod>
7359

74-
<!-- Properties set from database results or declared for future use -->
75-
<PossiblyUnusedProperty>
76-
<errorLevel type="suppress">
77-
<directory name="src/backend/Core/Entity" />
78-
<directory name="src/backend/Controllers" />
79-
</errorLevel>
80-
</PossiblyUnusedProperty>
81-
82-
<!-- Classes instantiated by router or kept for API completeness -->
83-
<UnusedClass>
84-
<errorLevel type="suppress">
85-
<directory name="src/backend/Controllers" />
86-
<directory name="src/backend/Core/Entity" />
87-
</errorLevel>
88-
</UnusedClass>
89-
9060
<!-- Views call global functions that may be dynamically loaded -->
9161
<UndefinedFunction>
9262
<errorLevel type="suppress">
@@ -98,82 +68,21 @@
9868
<RedundantCondition>
9969
<errorLevel type="suppress">
10070
<directory name="src/backend/Views" />
101-
<directory name="src/backend/Services" />
102-
<directory name="src/backend/Core" />
10371
</errorLevel>
10472
</RedundantCondition>
10573

74+
<!-- Views receive variables from controllers via extract(), psalm cannot infer types -->
10675
<TypeDoesNotContainType>
10776
<errorLevel type="suppress">
10877
<directory name="src/backend/Views" />
10978
</errorLevel>
11079
</TypeDoesNotContainType>
11180

112-
<!-- Defensive casts for type safety with dynamic data -->
113-
<RedundantCast>
114-
<errorLevel type="suppress">
115-
<directory name="src/backend/Views" />
116-
<directory name="src/backend/Services" />
117-
<directory name="src/backend/Core" />
118-
</errorLevel>
119-
</RedundantCast>
120-
12181
<!-- Return value may not be used by callers -->
12282
<PossiblyUnusedReturnValue>
12383
<errorLevel type="suppress">
12484
<directory name="src/backend/Services" />
12585
</errorLevel>
12686
</PossiblyUnusedReturnValue>
127-
128-
<!-- Services handle data from various sources with different types -->
129-
<InvalidReturnType>
130-
<errorLevel type="suppress">
131-
<directory name="src/backend/Services" />
132-
</errorLevel>
133-
</InvalidReturnType>
134-
135-
<!-- Foreach values used for iteration control only -->
136-
<UnusedForeachValue>
137-
<errorLevel type="suppress">
138-
<directory name="src/backend/Services" />
139-
<directory name="src/backend/Controllers" />
140-
</errorLevel>
141-
</UnusedForeachValue>
142-
143-
<!-- DOMNameSpaceNode has attributes in practice -->
144-
<UndefinedPropertyFetch>
145-
<errorLevel type="suppress">
146-
<directory name="src/backend/Services" />
147-
</errorLevel>
148-
</UndefinedPropertyFetch>
149-
150-
<!-- Dynamic array access patterns -->
151-
<InvalidArrayOffset>
152-
<errorLevel type="suppress">
153-
<directory name="src/backend/Services" />
154-
</errorLevel>
155-
</InvalidArrayOffset>
156-
157-
<!-- Unused function calls that have side effects -->
158-
<UnusedFunctionCall>
159-
<errorLevel type="suppress">
160-
<directory name="src/backend/Services" />
161-
</errorLevel>
162-
</UnusedFunctionCall>
163-
164-
<!-- Var annotations for clarity in views/controllers -->
165-
<UnnecessaryVarAnnotation>
166-
<errorLevel type="suppress">
167-
<directory name="src/backend/Views" />
168-
<directory name="src/backend/Controllers" />
169-
</errorLevel>
170-
</UnnecessaryVarAnnotation>
171-
172-
<!-- shell_exec used for feature detection (MeCab) -->
173-
<ForbiddenCode>
174-
<errorLevel type="suppress">
175-
<directory name="src/backend/Services" />
176-
</errorLevel>
177-
</ForbiddenCode>
17887
</issueHandlers>
17988
</psalm>

src/backend/Controllers/BaseController.php

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,11 @@
4141
abstract class BaseController
4242
{
4343
/**
44-
* Database connection (may be null if session_utility.php not yet loaded)
45-
*
46-
* @var \mysqli|null
47-
*/
48-
protected ?\mysqli $db = null;
49-
50-
/**
51-
* Initialize controller with database connection.
52-
*
53-
* Note: The database connection may not be available until Globals are
54-
* loaded by the controller action.
44+
* Initialize controller.
5545
*/
5646
public function __construct()
5747
{
58-
$this->db = \Lwt\Core\Globals::getDbConnection();
48+
// Base initialization - subclasses can override
5949
}
6050

6151
/**

src/backend/Controllers/TermTagsController.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
* @license Unlicense <http://unlicense.org/>
3737
* @link https://hugofara.github.io/lwt/docs/php/
3838
* @since 3.0.0
39+
*
40+
* @psalm-suppress UnusedClass - Used via string-based routing in routes.php
3941
*/
4042
class TermTagsController extends AbstractCrudController
4143
{

src/backend/Controllers/TextController.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,7 @@ public function importLong(array $params): void
580580
* @return void
581581
*
582582
* @psalm-suppress UnusedVariable Variables are used in included view files
583+
* @psalm-suppress UnusedParam Used in included view file
583584
*/
584585
private function importLongForm(int $maxInputVars): void
585586
{

src/backend/Controllers/TextTagsController.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
* @license Unlicense <http://unlicense.org/>
3737
* @link https://hugofara.github.io/lwt/docs/php/
3838
* @since 3.0.0
39+
*
40+
* @psalm-suppress UnusedClass - Used via string-based routing in routes.php
3941
*/
4042
class TextTagsController extends AbstractCrudController
4143
{

src/backend/Controllers/WordController.php

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ public function edit(array $params): void
161161
$fromAnn = $this->param("fromAnn");
162162

163163
if ($this->hasParam('op')) {
164-
$this->handleEditOperation($fromAnn);
164+
$this->handleEditOperation();
165165
} else {
166166
$wid = ($this->hasParam("wid") && is_numeric($this->param('wid')))
167167
? $this->paramInt('wid', -1)
@@ -177,11 +177,9 @@ public function edit(array $params): void
177177
/**
178178
* Handle save/update operation for word edit.
179179
*
180-
* @param string $fromAnn From annotation flag
181-
*
182180
* @return void
183181
*/
184-
private function handleEditOperation(string $fromAnn): void
182+
private function handleEditOperation(): void
185183
{
186184
$textlc = trim(\Lwt\Database\Escaping::prepareTextdata($this->param("WoTextLC")));
187185
$text = trim(\Lwt\Database\Escaping::prepareTextdata($this->param("WoText")));
@@ -587,14 +585,7 @@ public function listEdit(array $params): void
587585

588586
// Handle mark actions
589587
if ($this->hasParam('markaction')) {
590-
$message = $this->handleMarkAction(
591-
$listService,
592-
$currenttext,
593-
$whLang,
594-
$whStat,
595-
$whQuery,
596-
$whTag
597-
);
588+
$message = $this->handleMarkAction($listService);
598589
}
599590

600591
// Handle all actions
@@ -708,21 +699,11 @@ private function isExportOrTestAction(): bool
708699
* Handle mark actions for selected words.
709700
*
710701
* @param WordListService $listService Service instance
711-
* @param string $textId Current text filter
712-
* @param string $whLang Language condition
713-
* @param string $whStat Status condition
714-
* @param string $whQuery Query condition
715-
* @param string $whTag Tag condition
716702
*
717703
* @return string Result message
718704
*/
719705
private function handleMarkAction(
720-
WordListService $listService,
721-
string $textId,
722-
string $whLang,
723-
string $whStat,
724-
string $whQuery,
725-
string $whTag
706+
WordListService $listService
726707
): string {
727708
$markaction = $this->param('markaction');
728709
$actiondata = $this->param('data');
@@ -1270,6 +1251,8 @@ private function displayMultiWordForm(): void
12701251
* @param int $len Number of words
12711252
*
12721253
* @return void
1254+
*
1255+
* @psalm-suppress UnusedParam $len is used in included view file
12731256
*/
12741257
private function displayNewMultiWordForm(string $text, int $tid, int $ord, int $len): void
12751258
{
@@ -1707,6 +1690,8 @@ public function bulkTranslate(array $params): void
17071690
* @param bool $cleanUp Whether to clean up right frames after save
17081691
*
17091692
* @return void
1693+
*
1694+
* @psalm-suppress UnusedParam $tid and $cleanUp are used in included view file
17101695
*/
17111696
private function handleBulkSave(array $terms, int $tid, bool $cleanUp): void
17121697
{

src/backend/Core/Database/TextParsing.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,8 @@ private static function parseJapaneseToDatabase(string $text, bool $useMaxSeID):
217217
// Special case for kazu (numbers)
218218
if ($last_node_type == 8 && $node_type == 8) {
219219
$lastKey = array_key_last($values);
220-
if ($lastKey !== null) {
221-
// Concatenate the previous value with the current term
222-
$values[$lastKey - 1][3] = $values[$lastKey - 1][3] . $term;
223-
}
220+
// Concatenate the previous value with the current term
221+
$values[$lastKey - 1][3] = $values[$lastKey - 1][3] . $term;
224222
// Remove last element to avoid repetition
225223
array_pop($values);
226224
}
@@ -951,7 +949,7 @@ public static function displayStatistics(int $lid, bool $rtlScript, bool $multiw
951949
'words' => [], // Will be populated from text-check-words-config
952950
'multiWords' => $mw,
953951
'nonWords' => [], // Will be populated from text-check-words-config
954-
'rtlScript' => (bool)$rtlScript
952+
'rtlScript' => $rtlScript
955953
]);
956954
echo '</script>';
957955
}

src/backend/Core/Database/UserScopedQuery.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ public static function insertValue(string $tableName): string
204204
return '';
205205
}
206206

207-
return ', ' . (int) $userId;
207+
return ', ' . $userId;
208208
}
209209

210210
/**
@@ -217,6 +217,8 @@ public static function insertValue(string $tableName): string
217217
* @param string $alias Optional table alias to prefix the column
218218
* @param string $parentTable Optional parent table for inherited scope (unused, for API compat)
219219
*
220+
* @psalm-suppress PossiblyUnusedParam $parentTable kept for API compatibility
221+
*
220222
* @return string SQL WHERE condition fragment (includes leading AND)
221223
*/
222224
public static function forTable(string $tableName, string $alias = '', string $parentTable = ''): string
@@ -236,7 +238,7 @@ public static function forTable(string $tableName, string $alias = '', string $p
236238
}
237239

238240
$columnRef = $alias !== '' ? "{$alias}.{$column}" : $column;
239-
return " AND {$columnRef} = " . (int) $userId;
241+
return " AND {$columnRef} = " . $userId;
240242
}
241243

242244
/**
@@ -250,6 +252,8 @@ public static function forTable(string $tableName, string $alias = '', string $p
250252
* @param string $alias Optional table alias
251253
* @param string $parentTable Optional parent table for inherited scope (unused, for API compat)
252254
*
255+
* @psalm-suppress PossiblyUnusedParam $parentTable kept for API compatibility
256+
*
253257
* @return string SQL WHERE condition fragment (includes leading AND)
254258
*/
255259
public static function forTablePrepared(
@@ -305,7 +309,7 @@ public static function whereClause(string $tableName, string $alias = ''): strin
305309
}
306310

307311
$columnRef = $alias !== '' ? "{$alias}.{$column}" : $column;
308-
return "WHERE {$columnRef} = " . (int) $userId;
312+
return "WHERE {$columnRef} = " . $userId;
309313
}
310314

311315
/**

src/backend/Core/Entity/GoogleTranslate.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@
3535
*/
3636
class GoogleTranslate
3737
{
38-
/** @var ''|list<string>|false */
38+
/**
39+
* @var ''|list<string>|false
40+
*
41+
* @psalm-suppress PossiblyUnusedProperty - Public property for external access
42+
*/
3943
public array|string|false $lastResult = "";
4044

4145
private ?string $langFrom = null;

src/backend/Core/Parser/Parsers/MecabParser.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ private function checkAvailability(): void
9191

9292
if (str_starts_with($os, 'LIN') || str_starts_with($os, 'DAR')) {
9393
// Linux or macOS
94+
/** @psalm-suppress ForbiddenCode shell_exec is required to check MeCab availability */
9495
$result = @shell_exec("command -v mecab 2>/dev/null");
9596
if ($result !== null && trim($result) !== '') {
9697
$this->mecabAvailable = true;
@@ -105,6 +106,7 @@ private function checkAvailability(): void
105106
'where mecab.exe 2>nul'
106107
];
107108
foreach ($checks as $check) {
109+
/** @psalm-suppress ForbiddenCode shell_exec is required to check MeCab availability */
108110
$result = @shell_exec($check);
109111
if ($result !== null && trim($result) !== '') {
110112
$this->mecabAvailable = true;

0 commit comments

Comments
 (0)