summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwn_ <invalid@email.com>2024-11-12 03:15:53 +0000
committerwn_ <invalid@email.com>2024-11-12 03:15:53 +0000
commita784305cc764a7e039ad87074f541db68a653a5a (patch)
tree508c428e11d5559c3c25ad01ffe1ba474f7da270
parente4c57769e005e75b80ec0fa206fed8ff69e58162 (diff)
Address PHPStan findings as of 2.0.1
-rw-r--r--classes/API.php39
-rw-r--r--classes/Counters.php26
-rw-r--r--classes/Digest.php2
-rw-r--r--classes/FeedItem_RSS.php2
-rw-r--r--classes/Feeds.php10
-rw-r--r--classes/Plugin.php4
-rw-r--r--classes/PluginHost.php3
-rw-r--r--classes/Pref_Feeds.php3
-rw-r--r--classes/Pref_Filters.php1
-rw-r--r--classes/Pref_Prefs.php14
-rw-r--r--classes/UserHelper.php1
-rw-r--r--include/errorhandler.php50
-rw-r--r--include/functions.php1
-rwxr-xr-xinclude/login_form.php18
-rw-r--r--index.php23
-rw-r--r--phpstan.neon13
-rw-r--r--prefs.php18
17 files changed, 108 insertions, 120 deletions
diff --git a/classes/API.php b/classes/API.php
index 6dbb1f246..d6d622c52 100644
--- a/classes/API.php
+++ b/classes/API.php
@@ -235,7 +235,7 @@ class API extends Handler {
}
function updateArticle(): bool {
- $article_ids = explode(",", clean($_REQUEST["article_ids"]));
+ $article_ids = array_filter(explode(",", clean($_REQUEST["article_ids"] ?? "")));
$mode = (int) clean($_REQUEST["mode"]);
$data = clean($_REQUEST["data"] ?? "");
$field_raw = (int)clean($_REQUEST["field"]);
@@ -550,26 +550,22 @@ class API extends Handler {
/* Virtual feeds */
- $vfeeds = PluginHost::getInstance()->get_feeds(Feeds::CATEGORY_SPECIAL);
-
- if (is_array($vfeeds)) {
- foreach ($vfeeds as $feed) {
- if (!implements_interface($feed['sender'], 'IVirtualFeed'))
- continue;
+ foreach (PluginHost::getInstance()->get_feeds(Feeds::CATEGORY_SPECIAL) as $feed) {
+ if (!implements_interface($feed['sender'], 'IVirtualFeed'))
+ continue;
- /** @var IVirtualFeed $feed['sender'] */
- $unread = $feed['sender']->get_unread($feed['id']);
+ /** @var IVirtualFeed $feed['sender'] */
+ $unread = $feed['sender']->get_unread($feed['id']);
- if ($unread || !$unread_only) {
- $row = [
- 'id' => PluginHost::pfeed_to_feed_id($feed['id']),
- 'title' => $feed['title'],
- 'unread' => $unread,
- 'cat_id' => Feeds::CATEGORY_SPECIAL,
- ];
+ if ($unread || !$unread_only) {
+ $row = [
+ 'id' => PluginHost::pfeed_to_feed_id($feed['id']),
+ 'title' => $feed['title'],
+ 'unread' => $unread,
+ 'cat_id' => Feeds::CATEGORY_SPECIAL,
+ ];
- array_push($feeds, $row);
- }
+ array_push($feeds, $row);
}
}
@@ -696,10 +692,11 @@ class API extends Handler {
if (!$is_cat && is_numeric($feed_id) && $feed_id < PLUGIN_FEED_BASE_INDEX && $feed_id > LABEL_BASE_INDEX) {
$pfeed_id = PluginHost::feed_to_pfeed_id($feed_id);
- /** @var IVirtualFeed|false $handler */
$handler = PluginHost::getInstance()->get_feed_handler($pfeed_id);
- if ($handler) {
+ if ($handler && implements_interface($handler, 'IVirtualFeed')) {
+ /** @var Plugin&IVirtualFeed $handler */
+
$params = array(
"feed" => $feed_id,
"limit" => $limit,
@@ -858,7 +855,7 @@ class API extends Handler {
array_push($headlines, $headline_row);
}
- } else if (is_numeric($result) && $result == -1) {
+ } else if ($result == -1) {
$headlines_header['first_id_changed'] = true;
}
diff --git a/classes/Counters.php b/classes/Counters.php
index 0f6b419ba..780dc82ab 100644
--- a/classes/Counters.php
+++ b/classes/Counters.php
@@ -264,25 +264,21 @@ class Counters {
array_push($ret, $cv);
}
- $feeds = PluginHost::getInstance()->get_feeds(Feeds::CATEGORY_SPECIAL);
+ foreach (PluginHost::getInstance()->get_feeds(Feeds::CATEGORY_SPECIAL) as $feed) {
+ /** @var IVirtualFeed $feed['sender'] */
- if (is_array($feeds)) {
- foreach ($feeds as $feed) {
- /** @var IVirtualFeed $feed['sender'] */
+ if (!implements_interface($feed['sender'], 'IVirtualFeed'))
+ continue;
- if (!implements_interface($feed['sender'], 'IVirtualFeed'))
- continue;
-
- $cv = [
- "id" => PluginHost::pfeed_to_feed_id($feed['id']),
- "counter" => $feed['sender']->get_unread($feed['id'])
- ];
+ $cv = [
+ "id" => PluginHost::pfeed_to_feed_id($feed['id']),
+ "counter" => $feed['sender']->get_unread($feed['id'])
+ ];
- if (method_exists($feed['sender'], 'get_total'))
- $cv["auxcounter"] = $feed['sender']->get_total($feed['id']);
+ if (method_exists($feed['sender'], 'get_total'))
+ $cv["auxcounter"] = $feed['sender']->get_total($feed['id']);
- array_push($ret, $cv);
- }
+ array_push($ret, $cv);
}
return $ret;
diff --git a/classes/Digest.php b/classes/Digest.php
index cad808711..287f5f8fc 100644
--- a/classes/Digest.php
+++ b/classes/Digest.php
@@ -163,7 +163,7 @@ class Digest
$article_labels = Article::_get_labels($line["ref_id"], $user_id);
$article_labels_formatted = "";
- if (is_array($article_labels) && count($article_labels) > 0) {
+ if (count($article_labels) > 0) {
$article_labels_formatted = implode(", ", array_map(fn($a) => $a[1], $article_labels));
}
diff --git a/classes/FeedItem_RSS.php b/classes/FeedItem_RSS.php
index b5710ef4f..207d54dfb 100644
--- a/classes/FeedItem_RSS.php
+++ b/classes/FeedItem_RSS.php
@@ -34,7 +34,7 @@ class FeedItem_RSS extends FeedItem_Common {
$links = $this->xpath->query("atom:link", $this->elem);
foreach ($links as $link) {
- if ($link && $link->hasAttribute("href") &&
+ if ($link->hasAttribute("href") &&
(!$link->hasAttribute("rel")
|| $link->getAttribute("rel") == "alternate"
|| $link->getAttribute("rel") == "standout")) {
diff --git a/classes/Feeds.php b/classes/Feeds.php
index 34540ff11..38c098724 100644
--- a/classes/Feeds.php
+++ b/classes/Feeds.php
@@ -103,12 +103,12 @@ class Feeds extends Handler_Protected {
$qfh_ret = [];
if (!$cat_view && is_numeric($feed) && $feed < PLUGIN_FEED_BASE_INDEX && $feed > LABEL_BASE_INDEX) {
-
- /** @var IVirtualFeed|false $handler */
$handler = PluginHost::getInstance()->get_feed_handler(
PluginHost::feed_to_pfeed_id($feed));
- if ($handler) {
+ if ($handler && implements_interface($handler, 'IVirtualFeed')) {
+ /** @var Plugin&IVirtualFeed $handler */
+
$options = array(
"limit" => $limit,
"view_mode" => $view_mode,
@@ -246,7 +246,7 @@ class Feeds extends Handler_Protected {
$label_cache = json_decode($label_cache, true);
if ($label_cache) {
- if ($label_cache["no-labels"] ?? 0 == 1)
+ if (($label_cache["no-labels"] ?? 0) == 1)
$labels = [];
else
$labels = $label_cache;
@@ -940,7 +940,7 @@ class Feeds extends Handler_Protected {
$feed_id = PluginHost::feed_to_pfeed_id($feed);
$handler = PluginHost::getInstance()->get_feed_handler($feed_id);
if (implements_interface($handler, 'IVirtualFeed')) {
- /** @var IVirtualFeed $handler */
+ /** @var Plugin&IVirtualFeed $handler */
return $handler->get_unread($feed_id);
} else {
return 0;
diff --git a/classes/Plugin.php b/classes/Plugin.php
index cc50ae75e..62211f338 100644
--- a/classes/Plugin.php
+++ b/classes/Plugin.php
@@ -76,7 +76,7 @@ abstract class Plugin {
*
* @return string */
function __($msgid) {
- /** @var Plugin $this -- this is a strictly template-related hack */
+ // this is a strictly template-related hack
return _dgettext(PluginHost::object_to_domain($this), $msgid);
}
@@ -87,7 +87,7 @@ abstract class Plugin {
*
* @return string */
function _ngettext($singular, $plural, $number) {
- /** @var Plugin $this -- this is a strictly template-related hack */
+ // this is a strictly template-related hack
return _dngettext(PluginHost::object_to_domain($this), $singular, $plural, $number);
}
diff --git a/classes/PluginHost.php b/classes/PluginHost.php
index 23ff03661..88eb5d2a4 100644
--- a/classes/PluginHost.php
+++ b/classes/PluginHost.php
@@ -386,6 +386,7 @@ class PluginHost {
* @param PluginHost::HOOK_* $type
*/
function del_hook(string $type, Plugin $sender): void {
+ /** @phpstan-ignore function.alreadyNarrowedType ($type might not exist) */
if (is_array($this->hooks[$type])) {
foreach (array_keys($this->hooks[$type]) as $prio) {
$key = array_search($sender, $this->hooks[$type][$prio]);
@@ -589,7 +590,7 @@ class PluginHost {
}
}
- /** @return array<string, array{'description': string, 'suffix': string, 'arghelp': string, 'class': Plugin}>> command type -> details array */
+ /** @return array<string, array{'description': string, 'suffix': string, 'arghelp': string, 'class': Plugin}> command type -> details array */
function get_commands() {
return $this->commands;
}
diff --git a/classes/Pref_Feeds.php b/classes/Pref_Feeds.php
index 5ca557c84..8101b9531 100644
--- a/classes/Pref_Feeds.php
+++ b/classes/Pref_Feeds.php
@@ -240,8 +240,7 @@ class Pref_Feeds extends Handler_Protected {
/**
* Uncategorized is a special case.
*
- * Define a minimal array shape to help PHPStan with the type of $cat['items']
- * @var array{items: array<int, array<string, mixed>>} $cat
+ * @var array{id: string, bare_id: int, auxcounter: int, name: string, items: array<int, array<string, mixed>>, type: 'category', checkbox: bool, unread: int, child_unread: int}
*/
$cat = [
'id' => 'CAT:0',
diff --git a/classes/Pref_Filters.php b/classes/Pref_Filters.php
index 7a477d7db..6e609b76c 100644
--- a/classes/Pref_Filters.php
+++ b/classes/Pref_Filters.php
@@ -714,7 +714,6 @@ class Pref_Filters extends Handler_Protected {
}
function editrule(): void {
- /** @var array<int, int|string> */
$feed_ids = explode(",", clean($_REQUEST["ids"]));
print json_encode([
diff --git a/classes/Pref_Prefs.php b/classes/Pref_Prefs.php
index dd28bd3f2..47d6886f9 100644
--- a/classes/Pref_Prefs.php
+++ b/classes/Pref_Prefs.php
@@ -177,7 +177,7 @@ class Pref_Prefs extends Handler_Protected {
$authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
if (implements_interface($authenticator, "IAuthModule2")) {
- /** @var IAuthModule2 $authenticator */
+ /** @var Plugin&IAuthModule2 $authenticator */
print format_notice($authenticator->change_password($_SESSION["uid"], $old_pw, $new_pw));
} else {
print "ERROR: ".format_error("Function not supported by authentication module.");
@@ -976,7 +976,7 @@ class Pref_Prefs extends Handler_Protected {
$authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
- /** @var Auth_Internal|false $authenticator -- this is only here to make check_password() visible to static analyzer */
+ /** @var Auth_Internal|null $authenticator -- this is only here to make check_password() visible to static analyzer */
if ($authenticator->check_password($_SESSION["uid"], $password)) {
if (UserHelper::enable_otp($_SESSION["uid"], $otp_check)) {
print "OK";
@@ -991,7 +991,7 @@ class Pref_Prefs extends Handler_Protected {
function otpdisable(): void {
$password = clean($_REQUEST["password"]);
- /** @var Auth_Internal|false $authenticator -- this is only here to make check_password() visible to static analyzer */
+ /** @var Auth_Internal|null $authenticator -- this is only here to make check_password() visible to static analyzer */
$authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
if ($authenticator->check_password($_SESSION["uid"], $password)) {
@@ -1316,14 +1316,8 @@ class Pref_Prefs extends Handler_Protected {
function updateLocalPlugins(): void {
if ($_SESSION["access_level"] >= UserHelper::ACCESS_LEVEL_ADMIN) {
- $plugins = explode(",", $_REQUEST["plugins"] ?? "");
-
- if ($plugins !== false) {
- $plugins = array_filter($plugins, 'strlen');
- }
-
+ $plugins = array_filter(explode(",", $_REQUEST["plugins"] ?? ""), "strlen");
$root_dir = Config::get_self_dir();
-
$rv = [];
if ($plugins) {
diff --git a/classes/UserHelper.php b/classes/UserHelper.php
index 0c2ed349b..6c294a9a8 100644
--- a/classes/UserHelper.php
+++ b/classes/UserHelper.php
@@ -503,7 +503,6 @@ class UserHelper {
return $authenticator->check_password($owner_uid, $password);
} else {
- /** @var Auth_Internal|false $authenticator -- this is only here to make check_password() visible to static analyzer */
$authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
if ($authenticator &&
diff --git a/include/errorhandler.php b/include/errorhandler.php
index ea464f77a..4f773bc19 100644
--- a/include/errorhandler.php
+++ b/include/errorhandler.php
@@ -2,40 +2,38 @@
/**
* @param array<int, array<string, mixed>> $trace
*/
-function format_backtrace($trace): string {
+function format_backtrace(array $trace): string {
$rv = "";
$idx = 1;
- if (is_array($trace)) {
- foreach ($trace as $e) {
- if (isset($e["file"]) && isset($e["line"])) {
- $fmt_args = [];
-
- if (is_array($e["args"] ?? false)) {
- foreach ($e["args"] as $a) {
- if (is_object($a)) {
- array_push($fmt_args, "{" . get_class($a) . "}");
- } else if (is_array($a)) {
- array_push($fmt_args, "[" . truncate_string(json_encode($a), 256, "...")) . "]";
- } else if (is_resource($a)) {
- array_push($fmt_args, truncate_string(get_resource_type($a), 256, "..."));
- } else if (is_string($a)) {
- array_push($fmt_args, truncate_string($a, 256, "..."));
- }
+ foreach ($trace as $e) {
+ if (isset($e["file"]) && isset($e["line"])) {
+ $fmt_args = [];
+
+ if (is_array($e["args"] ?? false)) {
+ foreach ($e["args"] as $a) {
+ if (is_object($a)) {
+ array_push($fmt_args, "{" . get_class($a) . "}");
+ } else if (is_array($a)) {
+ array_push($fmt_args, "[" . truncate_string(json_encode($a), 256, "...")) . "]";
+ } else if (is_resource($a)) {
+ array_push($fmt_args, truncate_string(get_resource_type($a), 256, "..."));
+ } else if (is_string($a)) {
+ array_push($fmt_args, truncate_string($a, 256, "..."));
}
}
+ }
- $filename = str_replace(dirname(__DIR__) . "/", "", $e["file"]);
+ $filename = str_replace(dirname(__DIR__) . "/", "", $e["file"]);
- $rv .= sprintf("%d. %s(%s): %s(%s)\n",
- $idx,
- $filename,
- $e["line"],
- $e["function"],
- implode(", ", $fmt_args));
+ $rv .= sprintf("%d. %s(%s): %s(%s)\n",
+ $idx,
+ $filename,
+ $e["line"],
+ $e["function"],
+ implode(", ", $fmt_args));
- $idx++;
- }
+ $idx++;
}
}
diff --git a/include/functions.php b/include/functions.php
index c32924743..a79a19711 100644
--- a/include/functions.php
+++ b/include/functions.php
@@ -123,6 +123,7 @@
// create a list like "en" => 0.8
$langs = array_combine($lang_parse[1], $lang_parse[4]);
+ /** @phpstan-ignore function.alreadyNarrowedType (PHP 7.4 will return false if array_value has an issue) */
if (is_array($langs)) {
// set default to 1 for any without q factor
foreach ($langs as $lang => $val) {
diff --git a/include/login_form.php b/include/login_form.php
index 0545a51be..5ff2b378e 100755
--- a/include/login_form.php
+++ b/include/login_form.php
@@ -39,16 +39,14 @@
<?php
foreach (PluginHost::getInstance()->get_plugins() as $n => $p) {
- if (method_exists($p, "get_login_js")) {
- $script = $p->get_login_js();
-
- if ($script) {
- echo "try {
- $script
- } catch (e) {
- console.warn('failed to initialize plugin JS: $n', e);
- }";
- }
+ $script = $p->get_login_js();
+
+ if ($script) {
+ echo "try {
+ $script
+ } catch (e) {
+ console.warn('failed to initialize plugin JS: $n', e);
+ }";
}
}
?>
diff --git a/index.php b/index.php
index a2a6d2373..ac37043cd 100644
--- a/index.php
+++ b/index.php
@@ -36,8 +36,9 @@
<style type="text/css">
<?php
foreach (PluginHost::getInstance()->get_plugins() as $p) {
- if (method_exists($p, "get_css")) {
- echo $p->get_css();
+ $css = $p->get_css();
+ if ($css) {
+ echo $css;
}
}
?>
@@ -73,16 +74,14 @@
<script type="text/javascript">
<?php
foreach (PluginHost::getInstance()->get_plugins() as $n => $p) {
- if (method_exists($p, "get_js")) {
- $script = $p->get_js();
-
- if ($script) {
- echo "try {
- $script
- } catch (e) {
- console.warn('failed to initialize plugin JS: $n', e);
- }";
- }
+ $script = $p->get_js();
+
+ if ($script) {
+ echo "try {
+ $script
+ } catch (e) {
+ console.warn('failed to initialize plugin JS: $n', e);
+ }";
}
}
?>
diff --git a/phpstan.neon b/phpstan.neon
index 8b0c352a2..fd5bc6be0 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -5,8 +5,17 @@ parameters:
maximumNumberOfProcesses: 4
reportUnmatchedIgnoredErrors: false
ignoreErrors:
- - '#Constant.*\b(SUBSTRING_FOR_DATE|SCHEMA_VERSION|SELF_USER_AGENT|LABEL_BASE_INDEX|PLUGIN_FEED_BASE_INDEX)\b.*not found#'
- - '#Comparison operation ">" between int<1, max> and 0 is always true.#'
+ # set_include_path detection issue
+ - identifier: requireOnce.fileNotFound
+
+ # undetected as DOMElement
+ - '#Call to an undefined method DOMNode::#'
+ - '#Access to an undefined property DOMNode::#'
+ - '#expects DOMElement, DOMNode given#'
+
+ # allow passing a 'strlen' string, etc. as the array_filter callback
+ - "/Parameter #2 \\$callback of function array_filter expects .+ '.+' given/"
+
- message: '##'
paths:
- lib/*
diff --git a/prefs.php b/prefs.php
index f1c7a0fa7..6884edb7c 100644
--- a/prefs.php
+++ b/prefs.php
@@ -64,16 +64,14 @@
<script type="text/javascript">
<?php
foreach (PluginHost::getInstance()->get_plugins() as $n => $p) {
- if (method_exists($p, "get_prefs_js")) {
- $script = $p->get_prefs_js();
-
- if ($script) {
- echo "try {
- $script
- } catch (e) {
- console.warn('failed to initialize plugin JS: $n', e);
- }";
- }
+ $script = $p->get_prefs_js();
+
+ if ($script) {
+ echo "try {
+ $script
+ } catch (e) {
+ console.warn('failed to initialize plugin JS: $n', e);
+ }";
}
}
?>