diff options
author | Alexandre Alapetite <alexandre@alapetite.fr> | 2025-02-23 17:08:17 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-23 17:08:17 +0100 |
commit | f7b4a1e74220af1d0db310f17ba1294862a32393 (patch) | |
tree | 349527d1e8538233d1ed337c5888973b6a0a1ccf /app | |
parent | b0b75dd635831e23a4241e52a9ecd5fce0fb26b9 (diff) | |
download | freshrss-f7b4a1e74220af1d0db310f17ba1294862a32393.tar.gz freshrss-f7b4a1e74220af1d0db310f17ba1294862a32393.zip |
PHPStan more checkImplicitMixed (#7339)
* PHPStan more checkImplicitMixed
* Draft Entry.php
* Finish Entry.php
* Finish FeedDAO.php and Themes.php
Diffstat (limited to 'app')
-rw-r--r-- | app/Models/Entry.php | 26 | ||||
-rw-r--r-- | app/Models/FeedDAO.php | 12 | ||||
-rw-r--r-- | app/Models/Themes.php | 4 | ||||
-rw-r--r-- | app/views/helpers/feed/update.phtml | 17 |
4 files changed, 40 insertions, 19 deletions
diff --git a/app/Models/Entry.php b/app/Models/Entry.php index fe0cf7429..2454e4831 100644 --- a/app/Models/Entry.php +++ b/app/Models/Entry.php @@ -65,7 +65,9 @@ class FreshRSS_Entry extends Minz_Model { } $dao['attributes'] = empty($dao['attributes']) ? [] : json_decode($dao['attributes'], true); - if (!is_array($dao['attributes'])) { + if (is_array($dao['attributes'])) { + $dao['attributes'] = array_filter($dao['attributes'], 'is_string', ARRAY_FILTER_USE_KEY); + } else { $dao['attributes'] = []; } @@ -168,7 +170,7 @@ class FreshRSS_Entry extends Minz_Model { return preg_match('/(?P<delim>[\'"])' . preg_quote($link, '/') . '(?P=delim)/', $html) == 1; } - /** @param array{'url'?:string,'length'?:int,'medium'?:string,'type'?:string} $enclosure */ + /** @param array{url?:string,length?:int,medium?:string,type?:string} $enclosure */ private static function enclosureIsImage(array $enclosure): bool { $elink = $enclosure['url'] ?? ''; $length = $enclosure['length'] ?? 0; @@ -230,15 +232,15 @@ HTML; continue; } $credits = $enclosure['credit'] ?? ''; - $description = nl2br($enclosure['description'] ?? '', true); - $length = $enclosure['length'] ?? 0; - $medium = $enclosure['medium'] ?? ''; - $mime = $enclosure['type'] ?? ''; + $description = is_string($enclosure['description'] ?? null) ? nl2br($enclosure['description'], true) : ''; + $length = is_numeric($enclosure['length'] ?? null) ? (int)$enclosure['length'] : 0; + $medium = is_string($enclosure['medium'] ?? null) ? $enclosure['medium'] : ''; + $mime = is_string($enclosure['type'] ?? null) ? $enclosure['type'] : ''; $thumbnails = $enclosure['thumbnails'] ?? null; if (!is_array($thumbnails)) { $thumbnails = []; } - $etitle = $enclosure['title'] ?? ''; + $etitle = is_string($enclosure['title'] ?? null) ? $enclosure['title'] : ''; $content .= "\n"; $content .= '<figure class="enclosure">'; @@ -249,16 +251,16 @@ HTML; } } - if (self::enclosureIsImage($enclosure)) { + if (self::enclosureIsImage(['url' => $elink, 'length' => $length, 'medium' => $medium, 'type' => $mime])) { $content .= '<p class="enclosure-content"><img src="' . $elink . '" alt="" title="' . $etitle . '" /></p>'; } elseif ($medium === 'audio' || str_starts_with($mime, 'audio')) { $content .= '<p class="enclosure-content"><audio preload="none" src="' . $elink - . ($length == null ? '' : '" data-length="' . (int)$length) + . ($length == null ? '' : '" data-length="' . $length) . ($mime == '' ? '' : '" data-type="' . htmlspecialchars($mime, ENT_COMPAT, 'UTF-8')) . '" controls="controls" title="' . $etitle . '"></audio> <a download="" href="' . $elink . '">💾</a></p>'; } elseif ($medium === 'video' || str_starts_with($mime, 'video')) { $content .= '<p class="enclosure-content"><video preload="none" src="' . $elink - . ($length == null ? '' : '" data-length="' . (int)$length) + . ($length == null ? '' : '" data-length="' . $length) . ($mime == '' ? '' : '" data-type="' . htmlspecialchars($mime, ENT_COMPAT, 'UTF-8')) . '" controls="controls" title="' . $etitle . '"></video> <a download="" href="' . $elink . '">💾</a></p>'; } else { //e.g. application, text, unknown @@ -273,7 +275,9 @@ HTML; $credits = [$credits]; } foreach ($credits as $credit) { - $content .= '<p class="enclosure-credits">© ' . $credit . '</p>'; + if (is_string($credit)) { + $content .= '<p class="enclosure-credits">© ' . $credit . '</p>'; + } } } if ($description != '') { diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php index 8f2791485..6b5f7f96a 100644 --- a/app/Models/FeedDAO.php +++ b/app/Models/FeedDAO.php @@ -117,7 +117,9 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo { // Merge existing and import attributes $existingAttributes = $feed_search->attributes(); $importAttributes = $feed->attributes(); - $feed->_attributes(array_replace_recursive($existingAttributes, $importAttributes)); + $mergedAttributes = array_replace_recursive($existingAttributes, $importAttributes); + $mergedAttributes = array_filter($mergedAttributes, 'is_string', ARRAY_FILTER_USE_KEY); + $feed->_attributes($mergedAttributes); // Update some values of the existing feed using the import $values = [ @@ -382,8 +384,10 @@ SQL; . 'ORDER BY `lastUpdate` ' . ($limit < 1 ? '' : 'LIMIT ' . intval($limit)); $stm = $this->pdo->query($sql); - if ($stm !== false) { - return self::daoToFeeds($stm->fetchAll(PDO::FETCH_ASSOC)); + if ($stm !== false && ($res = $stm->fetchAll(PDO::FETCH_ASSOC)) !== false) { + /** @var list<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}> $res */ + return self::daoToFeeds($res); } else { $info = $this->pdo->errorInfo(); /** @var array{0:string,1:int,2:string} $info */ @@ -613,6 +617,6 @@ SQL; return -1; } $res = $stm->fetchAll(PDO::FETCH_COLUMN, 0); - return (int)($res[0] ?? 0); + return is_numeric($res[0] ?? null) ? (int)$res[0] : 0; } } diff --git a/app/Models/Themes.php b/app/Models/Themes.php index 033bbe2a0..2b5bff2f7 100644 --- a/app/Models/Themes.php +++ b/app/Models/Themes.php @@ -92,14 +92,14 @@ class FreshRSS_Themes extends Minz_Model { } public static function title(string $name): string { - static $titles = [ + $titles = [ 'opml-dyn' => 'sub.category.dynamic_opml', ]; return $titles[$name] ?? ''; } public static function alt(string $name): string { - static $alts = [ + $alts = [ 'add' => '➕', //✚ 'all' => '☰', 'bookmark-add' => '➕', //✚ diff --git a/app/views/helpers/feed/update.phtml b/app/views/helpers/feed/update.phtml index 92fedd992..54d3e77a0 100644 --- a/app/views/helpers/feed/update.phtml +++ b/app/views/helpers/feed/update.phtml @@ -781,8 +781,14 @@ ?> </select> <div class="stick"> + <?php + $postFields = $this->feed->attributeArray('curl_params')[CURLOPT_POSTFIELDS] ?? ''; + if (!is_string($postFields)) { + $postFields = ''; + } + ?> <input type="text" name="curl_fields" id="curl_fields" value="<?= - htmlspecialchars($this->feed->attributeArray('curl_params')[CURLOPT_POSTFIELDS] ?? '', ENT_COMPAT, 'UTF-8') + htmlspecialchars($postFields, ENT_COMPAT, 'UTF-8') ?>" placeholder="<?= _t('sub.feed.method_postparams') ?>" /> </div> <p class="help"><?= _i('help') ?> <?= _t('sub.feed.method_help') ?></p> @@ -810,8 +816,15 @@ <div class="form-group"> <label class="group-name" for="http_headers"><?= _t('sub.feed.http_headers') ?></label> <div class="group-controls"> + <?php + $httpHeaders = $this->feed->attributeArray('curl_params')[CURLOPT_HTTPHEADER] ?? []; + if (!is_array($httpHeaders)) { + $httpHeaders = []; + } + $httpHeaders = array_filter($httpHeaders, 'is_string'); + ?> <textarea class="valid-json" id="http_headers" name="http_headers" rows="3" cols="64" spellcheck="false"><?php - foreach ($this->feed->attributeArray('curl_params')[CURLOPT_HTTPHEADER] ?? [] as $header) { + foreach ($httpHeaders as $header) { echo htmlspecialchars($header, ENT_NOQUOTES, 'UTF-8'), PHP_EOL; } ?></textarea> |