Просмотр исходного кода

PHPStan: pass checkImplicitMixed (#7642)

* PHPStan: pass checkImplicitMixed

* Complete
Alexandre Alapetite 10 месяцев назад
Родитель
Сommit
4de7d0b813
5 измененных файлов с 40 добавлено и 16 удалено
  1. 9 2
      app/Models/EntryDAO.php
  2. 3 0
      app/Models/TagDAO.php
  3. 15 8
      app/Services/ImportService.php
  4. 12 5
      phpstan-next.neon
  5. 1 1
      phpstan.dist.neon

+ 9 - 2
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;

+ 3 - 0
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'],

+ 15 - 8
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];

+ 12 - 5
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

+ 1 - 1
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