Address PHPStan findings as of 2.0.1
This commit is contained in:
@@ -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);
|
||||
foreach (PluginHost::getInstance()->get_feeds(Feeds::CATEGORY_SPECIAL) as $feed) {
|
||||
if (!implements_interface($feed['sender'], 'IVirtualFeed'))
|
||||
continue;
|
||||
|
||||
if (is_array($vfeeds)) {
|
||||
foreach ($vfeeds 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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([
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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 = [];
|
||||
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, "..."));
|
||||
}
|
||||
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"]);
|
||||
|
||||
$rv .= sprintf("%d. %s(%s): %s(%s)\n",
|
||||
$idx,
|
||||
$filename,
|
||||
$e["line"],
|
||||
$e["function"],
|
||||
implode(", ", $fmt_args));
|
||||
|
||||
$idx++;
|
||||
}
|
||||
|
||||
$filename = str_replace(dirname(__DIR__) . "/", "", $e["file"]);
|
||||
|
||||
$rv .= sprintf("%d. %s(%s): %s(%s)\n",
|
||||
$idx,
|
||||
$filename,
|
||||
$e["line"],
|
||||
$e["function"],
|
||||
implode(", ", $fmt_args));
|
||||
|
||||
$idx++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
$script = $p->get_login_js();
|
||||
|
||||
if ($script) {
|
||||
echo "try {
|
||||
$script
|
||||
} catch (e) {
|
||||
console.warn('failed to initialize plugin JS: $n', e);
|
||||
}";
|
||||
}
|
||||
if ($script) {
|
||||
echo "try {
|
||||
$script
|
||||
} catch (e) {
|
||||
console.warn('failed to initialize plugin JS: $n', e);
|
||||
}";
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
21
index.php
21
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();
|
||||
$script = $p->get_js();
|
||||
|
||||
if ($script) {
|
||||
echo "try {
|
||||
$script
|
||||
} catch (e) {
|
||||
console.warn('failed to initialize plugin JS: $n', e);
|
||||
}";
|
||||
}
|
||||
if ($script) {
|
||||
echo "try {
|
||||
$script
|
||||
} catch (e) {
|
||||
console.warn('failed to initialize plugin JS: $n', e);
|
||||
}";
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
13
phpstan.neon
13
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/*
|
||||
|
||||
16
prefs.php
16
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();
|
||||
$script = $p->get_prefs_js();
|
||||
|
||||
if ($script) {
|
||||
echo "try {
|
||||
$script
|
||||
} catch (e) {
|
||||
console.warn('failed to initialize plugin JS: $n', e);
|
||||
}";
|
||||
}
|
||||
if ($script) {
|
||||
echo "try {
|
||||
$script
|
||||
} catch (e) {
|
||||
console.warn('failed to initialize plugin JS: $n', e);
|
||||
}";
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user