aboutsummaryrefslogtreecommitdiff
path: root/app/Models/FeedDAO.php
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2024-12-27 12:12:49 +0100
committerGravatar GitHub <noreply@github.com> 2024-12-27 12:12:49 +0100
commitb1d24fbdb7d1cc948c946295035dad6df550fb7e (patch)
tree7b4365a04097a779659474fbb9281a9661512522 /app/Models/FeedDAO.php
parent897e4a3f4a273d50c28157edb67612b2d7fa2e6f (diff)
PHPStan 2.0 (#7131)
* PHPStan 2.0 fix https://github.com/FreshRSS/FreshRSS/issues/6989 https://github.com/phpstan/phpstan/releases/tag/2.0.0 https://github.com/phpstan/phpstan/blob/2.0.x/UPGRADING.md * More * More * Done * fix i18n CLI * Restore a PHPStan Next test For work towards PHPStan Level 10 * 4 more on Level 10 * fix getTagsForEntry * API at Level 10 * More Level 10 * Finish Minz at Level 10 * Finish CLI at Level 10 * Finish Controllers at Level 10 * More Level 10 * More * Pass bleedingEdge * Clean PHPStan options and add TODOs * Level 10 for main config * More * Consitency array vs. list * Sanitize themes get_infos * Simplify TagDAO->getTagsForEntries() * Finish reportAnyTypeWideningInVarTag * Prepare checkBenevolentUnionTypes and checkImplicitMixed * Fixes * Refix * Another fix * Casing of __METHOD__ constant
Diffstat (limited to 'app/Models/FeedDAO.php')
-rw-r--r--app/Models/FeedDAO.php87
1 files changed, 37 insertions, 50 deletions
diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php
index fa52838ca..676b93b7f 100644
--- a/app/Models/FeedDAO.php
+++ b/app/Models/FeedDAO.php
@@ -7,18 +7,18 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo {
if ($this->pdo->inTransaction()) {
$this->pdo->commit();
}
- Minz_Log::warning(__method__ . ': ' . $name);
+ Minz_Log::warning(__METHOD__ . ': ' . $name);
try {
if ($name === 'kind') { //v1.20.0
return $this->pdo->exec('ALTER TABLE `_feed` ADD COLUMN kind SMALLINT DEFAULT 0') !== false;
}
} catch (Exception $e) {
- Minz_Log::error(__method__ . ' error: ' . $e->getMessage());
+ Minz_Log::error(__METHOD__ . ' error: ' . $e->getMessage());
}
return false;
}
- /** @param array<int|string> $errorInfo */
+ /** @param array{0:string,1:int,2:string} $errorInfo */
protected function autoUpdateDb(array $errorInfo): bool {
if (isset($errorInfo[0])) {
if ($errorInfo[0] === FreshRSS_DatabaseDAO::ER_BAD_FIELD_ERROR || $errorInfo[0] === FreshRSS_DatabaseDAOPGSQL::UNDEFINED_COLUMN) {
@@ -34,8 +34,8 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo {
}
/**
- * @param array{'url':string,'kind':int,'category':int,'name':string,'website':string,'description':string,'lastUpdate':int,'priority'?:int,
- * 'pathEntries'?:string,'httpAuth':string,'error':int|bool,'ttl'?:int,'attributes'?:string|array<string|mixed>} $valuesTmp
+ * @param array{url:string,kind:int,category:int,name:string,website:string,description:string,lastUpdate:int,priority?:int,
+ * pathEntries?:string,httpAuth:string,error:int|bool,ttl?:int,attributes?:string|array<string|mixed>} $valuesTmp
*/
public function addFeed(array $valuesTmp): int|false {
$sql = 'INSERT INTO `_feed` (url, kind, category, name, website, description, `lastUpdate`, priority, `pathEntries`, `httpAuth`, error, ttl, attributes)
@@ -72,6 +72,7 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo {
return $feedId === false ? false : (int)$feedId;
} else {
$info = $stm === false ? $this->pdo->errorInfo() : $stm->errorInfo();
+ /** @var array{0:string,1:int,2:string} $info */
if ($this->autoUpdateDb($info)) {
return $this->addFeed($valuesTmp);
}
@@ -177,6 +178,7 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo {
return true;
} else {
$info = $stm === false ? $this->pdo->errorInfo() : $stm->errorInfo();
+ /** @var array{0:string,1:int,2:string} $info */
if ($this->autoUpdateDb($info)) {
return $this->updateFeed($id, $originalValues);
}
@@ -290,8 +292,8 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo {
}
}
- /** @return Traversable<array{'id':int,'url':string,'kind':int,'category':int,'name':string,'website':string,'description':string,'lastUpdate':int,'priority'?:int,
- * 'pathEntries'?:string,'httpAuth':string,'error':int|bool,'ttl'?:int,'attributes'?:string}> */
+ /** @return Traversable<array{id:int,url:string,kind:int,category:int,name:string,website:string,description:string,lastUpdate:int,priority?:int,
+ * pathEntries?:string,httpAuth:string,error:int|bool,ttl?:int,attributes?:string}> */
public function selectAll(): Traversable {
$sql = <<<'SQL'
SELECT id, url, kind, category, name, website, description, `lastUpdate`,
@@ -301,16 +303,17 @@ SQL;
$stm = $this->pdo->query($sql);
if ($stm !== false) {
while ($row = $stm->fetch(PDO::FETCH_ASSOC)) {
- /** @var array{'id':int,'url':string,'kind':int,'category':int,'name':string,'website':string,'description':string,'lastUpdate':int,'priority'?:int,
- * 'pathEntries'?:string,'httpAuth':string,'error':int|bool,'ttl'?:int,'attributes'?:string} $row */
+ /** @var array{id:int,url:string,kind:int,category:int,name:string,website:string,description:string,lastUpdate:int,priority?:int,
+ * pathEntries?:string,httpAuth:string,error:int|bool,ttl?:int,attributes?:string} $row */
yield $row;
}
} else {
$info = $this->pdo->errorInfo();
+ /** @var array{0:string,1:int,2:string} $info */
if ($this->autoUpdateDb($info)) {
yield from $this->selectAll();
} else {
- Minz_Log::error(__method__ . ' error: ' . json_encode($info));
+ Minz_Log::error(__METHOD__ . ' error: ' . json_encode($info));
}
}
}
@@ -318,40 +321,34 @@ SQL;
public function searchById(int $id): ?FreshRSS_Feed {
$sql = 'SELECT * FROM `_feed` WHERE id=:id';
$res = $this->fetchAssoc($sql, [':id' => $id]);
- if ($res == null) {
+ if (!is_array($res)) {
return null;
}
- /** @var array<int,array{'url':string,'kind':int,'category':int,'name':string,'website':string,'lastUpdate':int,
- * 'priority'?:int,'pathEntries'?:string,'httpAuth':string,'error':int,'ttl'?:int,'attributes'?:string}> $res */
- $feeds = self::daoToFeeds($res);
- return $feeds[$id] ?? null;
+ $feeds = self::daoToFeeds($res); // @phpstan-ignore argument.type
+ return $feeds[0] ?? null;
}
public function searchByUrl(string $url): ?FreshRSS_Feed {
$sql = 'SELECT * FROM `_feed` WHERE url=:url';
$res = $this->fetchAssoc($sql, [':url' => $url]);
- /** @var array<int,array{'url':string,'kind':int,'category':int,'name':string,'website':string,'lastUpdate':int,
- * 'priority'?:int,'pathEntries'?:string,'httpAuth':string,'error':int,'ttl'?:int,'attributes'?:string}> $res */
- return empty($res[0]) ? null : (current(self::daoToFeeds($res)) ?: null);
+ return empty($res[0]) ? null : (current(self::daoToFeeds($res)) ?: null); // @phpstan-ignore argument.type
}
- /** @return array<int> */
+ /** @return list<int> */
public function listFeedsIds(): array {
$sql = 'SELECT id FROM `_feed`';
- /** @var array<int> $res */
+ /** @var list<int> $res */
$res = $this->fetchColumn($sql, 0) ?? [];
return $res;
}
/**
- * @return array<int,FreshRSS_Feed>
+ * @return list<FreshRSS_Feed>
*/
public function listFeeds(): array {
$sql = 'SELECT * FROM `_feed` ORDER BY name';
$res = $this->fetchAssoc($sql);
- /** @var array<array{'url':string,'kind':int,'category':int,'name':string,'website':string,'lastUpdate':int,
- * 'priority':int,'pathEntries':string,'httpAuth':string,'error':int,'ttl':int,'attributes':string}>|null $res */
- return $res == null ? [] : self::daoToFeeds($res);
+ return $res == null ? [] : self::daoToFeeds($res); // @phpstan-ignore argument.type
}
/** @return array<string,string> */
@@ -363,7 +360,7 @@ SQL;
$sql .= 'WHERE id_feed=' . intval($id_feed);
}
$res = $this->fetchAssoc($sql);
- /** @var array<array{'id_feed':int,'newest_item_us':string}>|null $res */
+ /** @var list<array{'id_feed':int,'newest_item_us':string}>|null $res */
if ($res == null) {
return [];
}
@@ -376,7 +373,7 @@ SQL;
/**
* @param int $defaultCacheDuration Use -1 to return all feeds, without filtering them by TTL.
- * @return array<int,FreshRSS_Feed>
+ * @return list<FreshRSS_Feed>
*/
public function listFeedsOrderUpdate(int $defaultCacheDuration = 3600, int $limit = 0): array {
$sql = 'SELECT id, url, kind, category, name, website, `lastUpdate`, `pathEntries`, `httpAuth`, ttl, attributes, `cache_nbEntries`, `cache_nbUnreads` '
@@ -391,6 +388,7 @@ SQL;
return self::daoToFeeds($stm->fetchAll(PDO::FETCH_ASSOC));
} else {
$info = $this->pdo->errorInfo();
+ /** @var array{0:string,1:int,2:string} $info */
if ($this->autoUpdateDb($info)) {
return $this->listFeedsOrderUpdate($defaultCacheDuration, $limit);
}
@@ -399,19 +397,19 @@ SQL;
}
}
- /** @return array<int,string> */
+ /** @return list<string> */
public function listTitles(int $id, int $limit = 0): array {
$sql = 'SELECT title FROM `_entry` WHERE id_feed=:id_feed ORDER BY id DESC'
. ($limit < 1 ? '' : ' LIMIT ' . intval($limit));
$res = $this->fetchColumn($sql, 0, [':id_feed' => $id]) ?? [];
- /** @var array<int,string> $res */
+ /** @var list<string> $res */
return $res;
}
/**
* @param bool|null $muted to include only muted feeds
* @param bool|null $errored to include only errored feeds
- * @return array<int,FreshRSS_Feed>
+ * @return list<FreshRSS_Feed>
*/
public function listByCategory(int $cat, ?bool $muted = null, ?bool $errored = null): array {
$sql = 'SELECT * FROM `_feed` WHERE category=:category';
@@ -422,18 +420,11 @@ SQL;
$sql .= ' AND error <> 0';
}
$res = $this->fetchAssoc($sql, [':category' => $cat]);
- if ($res == null) {
+ if (!is_array($res)) {
return [];
}
-
- /**
- * @var array<int,array{'url':string,'kind':int,'category':int,'name':string,'website':string,'lastUpdate':int,
- * 'priority'?:int,'pathEntries'?:string,'httpAuth':string,'error':int,'ttl'?:int,'attributes'?:string}> $res
- */
- $feeds = self::daoToFeeds($res);
-
- uasort($feeds, static fn(FreshRSS_Feed $a, FreshRSS_Feed $b) => strnatcasecmp($a->name(), $b->name()));
-
+ $feeds = self::daoToFeeds($res); // @phpstan-ignore argument.type
+ usort($feeds, static fn(FreshRSS_Feed $a, FreshRSS_Feed $b) => strnatcasecmp($a->name(), $b->name()));
return $feeds;
}
@@ -576,23 +567,19 @@ SQL;
}
/**
- * @param array<int,array{'id'?:int,'url'?:string,'kind'?:int,'category'?:int,'name'?:string,'website'?:string,'description'?:string,'lastUpdate'?:int,'priority'?:int,
- * 'pathEntries'?:string,'httpAuth'?:string,'error'?:int|bool,'ttl'?:int,'attributes'?:string,'cache_nbUnreads'?:int,'cache_nbEntries'?:int}> $listDAO
- * @return array<int,FreshRSS_Feed>
+ * @param array<array{id?:int,url?:string,kind?:int,category?:int,name?:string,website?:string,description?:string,lastUpdate?:int,priority?:int,
+ * pathEntries?:string,httpAuth?:string,error?:int|bool,ttl?:int,attributes?:string,cache_nbUnreads?:int,cache_nbEntries?:int}> $listDAO
+ * @return list<FreshRSS_Feed>
*/
public static function daoToFeeds(array $listDAO, ?int $catID = null): array {
$list = [];
- foreach ($listDAO as $key => $dao) {
- FreshRSS_DatabaseDAO::pdoInt($dao, ['id', 'kind', 'category', 'lastUpdate', 'priority', 'error', 'ttl', 'cache_nbUnreads', 'cache_nbEntries']);
- if (!isset($dao['name'])) {
+ foreach ($listDAO as $dao) {
+ if (!is_string($dao['name'] ?? null)) {
continue;
}
- if (isset($dao['id'])) {
- $key = (int)$dao['id'];
- }
if ($catID === null) {
- $category = $dao['category'] ?? 0;
+ $category = is_numeric($dao['category'] ?? null) ? (int)$dao['category'] : 0;
} else {
$category = $catID;
}
@@ -615,7 +602,7 @@ SQL;
if (isset($dao['id'])) {
$myFeed->_id($dao['id']);
}
- $list[$key] = $myFeed;
+ $list[] = $myFeed;
}
return $list;