aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/app
diff options
context:
space:
mode:
authorAlexandre Alapetite <alexandre@alapetite.fr>2025-02-23 17:08:17 +0100
committerGitHub <noreply@github.com>2025-02-23 17:08:17 +0100
commitf7b4a1e74220af1d0db310f17ba1294862a32393 (patch)
tree349527d1e8538233d1ed337c5888973b6a0a1ccf /app
parentb0b75dd635831e23a4241e52a9ecd5fce0fb26b9 (diff)
downloadfreshrss-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.php26
-rw-r--r--app/Models/FeedDAO.php12
-rw-r--r--app/Models/Themes.php4
-rw-r--r--app/views/helpers/feed/update.phtml17
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>