diff options
| -rw-r--r-- | app/Models/EntryDAO.php | 11 | ||||
| -rw-r--r-- | app/Models/TagDAO.php | 3 | ||||
| -rw-r--r-- | app/Services/ImportService.php | 23 | ||||
| -rw-r--r-- | phpstan-next.neon | 17 | ||||
| -rw-r--r-- | phpstan.dist.neon | 2 |
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 |
