aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2025-06-04 14:00:33 +0200
committerGravatar GitHub <noreply@github.com> 2025-06-04 14:00:33 +0200
commit4de7d0b81310c788365fd3d2ab28dfbbccb5b171 (patch)
tree9e1217892a1f6a3ee33611ff739aa46cfb6bd825
parent2b94cffeab0dfd66fcef15b6295efba24319b555 (diff)
PHPStan: pass checkImplicitMixed (#7642)
* PHPStan: pass checkImplicitMixed * Complete
-rw-r--r--app/Models/EntryDAO.php11
-rw-r--r--app/Models/TagDAO.php3
-rw-r--r--app/Services/ImportService.php23
-rw-r--r--phpstan-next.neon17
-rw-r--r--phpstan.dist.neon2
5 files changed, 40 insertions, 16 deletions
diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php
index af859045d..68746c380 100644
--- a/app/Models/EntryDAO.php
+++ b/app/Models/EntryDAO.php
@@ -43,7 +43,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
protected static function sqlRegex(string $expression, string $regex, array &$values): string {
// The implementation of this function is solely for MySQL and MariaDB
static $databaseDAOMySQL = null;
- if ($databaseDAOMySQL === null) {
+ if (!($databaseDAOMySQL instanceof FreshRSS_DatabaseDAO)) {
$databaseDAOMySQL = new FreshRSS_DatabaseDAO();
}
@@ -205,6 +205,8 @@ SQL;
return true;
} else {
$info = $this->addEntryPrepared == false ? $this->pdo->errorInfo() : $this->addEntryPrepared->errorInfo();
+ /** @var array{id:string,guid:string,title:string,author:string,content:string,link:string,date:int,lastSeen:int,hash:string,
+ * is_read:bool|int|null,is_favorite:bool|int|null,id_feed:int,tags:string,attributes?:null|string|array<string,mixed>} $valuesTmp */
/** @var array{0:string,1:int,2:string} $info */
if ($this->autoUpdateDb($info)) {
$this->addEntryPrepared = null;
@@ -315,6 +317,8 @@ SQL;
return true;
} else {
$info = $this->updateEntryPrepared == false ? $this->pdo->errorInfo() : $this->updateEntryPrepared->errorInfo();
+ /** @var array{id:string,guid:string,title:string,author:string,content:string,link:string,date:int,lastSeen:int,hash:string,
+ * is_read:bool|int|null,is_favorite:bool|int|null,id_feed:int,tags:string,attributes:array<string,mixed>} $valuesTmp */
/** @var array{0:string,1:int,2:string} $info */
if ($this->autoUpdateDb($info)) {
return $this->updateEntry($valuesTmp);
@@ -1461,7 +1465,9 @@ SQL;
[$values, $sql] = $this->sqlListWhere($type, $id, $state, $filters, id_min: $id_min, id_max: $id_max, order: $order,
continuation_id: $continuation_id, continuation_value: $continuation_value, limit: $limit, offset: $offset);
$stm = $this->pdo->prepare($sql);
- if ($stm !== false && $stm->execute($values) && ($res = $stm->fetchAll(PDO::FETCH_COLUMN, 0)) !== false) {
+ if ($stm !== false && $stm->execute($values)) {
+ /** @var list<int|numeric-string> $res */
+ $res = $stm->fetchAll(PDO::FETCH_COLUMN, 0);
$res = array_map('strval', $res);
/** @var list<numeric-string> $res */
return $res;
@@ -1496,6 +1502,7 @@ SQL;
if ($stm !== false && $stm->execute($values)) {
$rows = $stm->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
+ /** @var array{guid:string,hex_hash:string} $row */
$result[$row['guid']] = $row['hex_hash'];
}
return $result;
diff --git a/app/Models/TagDAO.php b/app/Models/TagDAO.php
index 65e322d5a..a253f37c1 100644
--- a/app/Models/TagDAO.php
+++ b/app/Models/TagDAO.php
@@ -199,6 +199,7 @@ SQL;
$stm = $this->pdo->query($sql);
if ($stm !== false && ($res = $stm->fetchAll(PDO::FETCH_ASSOC)) !== false) {
+ /** @var list<array{id:int,name:string,unreads:int}> $res */
return self::daoToTags($res);
} else {
$info = $this->pdo->errorInfo();
@@ -236,6 +237,7 @@ SQL;
$stm = $this->pdo->query($sql);
if ($stm !== false) {
$res = $stm->fetchAll(PDO::FETCH_ASSOC);
+ /** @var list<array{count:int|numeric-string}> $res */
return (int)$res[0]['count'];
}
$info = $this->pdo->errorInfo();
@@ -334,6 +336,7 @@ SQL;
if ($stm !== false && $stm->execute($values) && ($lines = $stm->fetchAll(PDO::FETCH_ASSOC)) !== false) {
$result = [];
foreach ($lines as $line) {
+ /** @var array{id:int,name:string,checked:bool|int} $line */
$result[] = [
'id' => (int)($line['id']),
'name' => $line['name'],
diff --git a/app/Services/ImportService.php b/app/Services/ImportService.php
index d32b62517..a2920dc74 100644
--- a/app/Services/ImportService.php
+++ b/app/Services/ImportService.php
@@ -41,6 +41,7 @@ class FreshRSS_Import_Service {
$opml_array = [];
try {
$libopml = new \marienfressinaud\LibOpml\LibOpml(false);
+ /** @var array{body:array<array<mixed>>} $opml_array */
$opml_array = $libopml->parseString($opml_file);
} catch (\marienfressinaud\LibOpml\Exception $e) {
self::log($e->getMessage());
@@ -382,13 +383,16 @@ class FreshRSS_Import_Service {
*
* @param array<array<mixed>> $outlines The outlines from which to extract the outlines.
* @param string $parent_category_name The name of the parent category of the current outlines.
- * @return array{0:array<string,array<string,string>>,1:array<string,array<array<string,string>>>}
+ * @return array{0:array<string,array<string,string>>,1:array<string,list<array<string,string>>>}
*/
private function loadFromOutlines(array $outlines, string $parent_category_name): array {
$categories_elements = [];
$categories_to_feeds = [];
foreach ($outlines as $outline) {
+ if (!is_array($outline)) {
+ continue;
+ }
// Get the categories and feeds from the child outline (it may
// return several categories and feeds if the outline is a category).
[$outline_categories, $outline_categories_to_feeds] = $this->loadFromOutline($outline, $parent_category_name);
@@ -398,10 +402,12 @@ class FreshRSS_Import_Service {
$categories_elements = array_merge($categories_elements, $outline_categories);
foreach ($outline_categories_to_feeds as $category_name => $feeds) {
+ if (!is_string($category_name) || !is_array($feeds)) {
+ continue;
+ }
if (!isset($categories_to_feeds[$category_name])) {
$categories_to_feeds[$category_name] = [];
}
-
$categories_to_feeds[$category_name] = array_merge(
$categories_to_feeds[$category_name],
$feeds
@@ -424,7 +430,7 @@ class FreshRSS_Import_Service {
* @param array<mixed> $outline The outline from which to extract the categories and feeds outlines.
* @param string $parent_category_name The name of the parent category of the current outline.
*
- * @return array{0:array<string,array<string,string>>,1:array<array<string,array<string,string>>>}
+ * @return array{0:array<string,array<string,string>>,1:array<string,list<array<string,string>>>}
*/
private function loadFromOutline(array $outline, string $parent_category_name): array {
$categories_elements = [];
@@ -441,7 +447,7 @@ class FreshRSS_Import_Service {
];
}
- if (isset($outline['@outlines'])) {
+ if (is_array($outline['@outlines'] ?? null)) {
// The outline has children, it’s probably a category
if (!empty($outline['text']) && is_string($outline['text'])) {
$category_name = $outline['text'];
@@ -451,10 +457,11 @@ class FreshRSS_Import_Service {
$category_name = $parent_category_name;
}
- [$categories_elements, $categories_to_feeds] = $this->loadFromOutlines($outline['@outlines'], $category_name);
+ $children = array_filter($outline['@outlines'], 'is_array');
+ [$categories_elements, $categories_to_feeds] = $this->loadFromOutlines($children, $category_name);
unset($outline['@outlines']);
- $categories_elements[$category_name] = $outline;
+ $categories_elements[$category_name] = array_filter($outline, static fn($value, $key) => is_string($key) && is_string($value), ARRAY_FILTER_USE_BOTH);
}
// The xmlUrl means it’s a feed URL: add the outline to the array if it exists.
@@ -462,8 +469,8 @@ class FreshRSS_Import_Service {
if (!isset($categories_to_feeds[$parent_category_name])) {
$categories_to_feeds[$parent_category_name] = [];
}
-
- $categories_to_feeds[$parent_category_name][] = $outline;
+ $feed = array_filter($outline, static fn($value, $key) => is_string($key) && is_string($value), ARRAY_FILTER_USE_BOTH);
+ $categories_to_feeds[$parent_category_name][] = $feed;
}
return [$categories_elements, $categories_to_feeds];
diff --git a/phpstan-next.neon b/phpstan-next.neon
index 19aaed28e..ff29085b8 100644
--- a/phpstan-next.neon
+++ b/phpstan-next.neon
@@ -4,12 +4,19 @@ includes:
parameters:
level: max
- checkImplicitMixed: true # TODO pass
strictRules:
- strictArrayFilter: false # TODO pass maybe
+ strictArrayFilter: true # TODO pass
excludePaths:
analyse:
# TODO: Update files below and remove them from this list
- - app/Models/EntryDAO.php
- - app/Models/TagDAO.php
- - app/Services/ImportService.php
+ - app/Controllers/configureController.php
+ - app/Controllers/feedController.php
+ - app/Controllers/subscriptionController.php
+ - app/Models/Entry.php
+ - app/Models/UserQuery.php
+ - cli/CliOption.php
+ - cli/CliOptionsParser.php
+ - cli/create-user.php
+ - cli/reconfigure.php
+ - cli/update-user.php
+ - lib/Minz/Migrator.php
diff --git a/phpstan.dist.neon b/phpstan.dist.neon
index 202591c83..867d7b50b 100644
--- a/phpstan.dist.neon
+++ b/phpstan.dist.neon
@@ -37,7 +37,7 @@ parameters:
- TMP_PATH
- USERS_PATH
checkBenevolentUnionTypes: true
- checkImplicitMixed: false # TODO pass
+ checkImplicitMixed: true
checkMissingOverrideMethodAttribute: true
checkTooWideReturnTypesInProtectedAndPublicMethods: true
reportAnyTypeWideningInVarTag: true