summaryrefslogtreecommitdiff
path: root/classes/pref
diff options
context:
space:
mode:
Diffstat (limited to 'classes/pref')
-rwxr-xr-xclasses/pref/feeds.php177
-rwxr-xr-xclasses/pref/filters.php102
-rw-r--r--classes/pref/labels.php23
-rw-r--r--classes/pref/prefs.php239
-rw-r--r--classes/pref/system.php21
-rw-r--r--classes/pref/users.php16
6 files changed, 324 insertions, 254 deletions
diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php
index ac0874259..47479e124 100755
--- a/classes/pref/feeds.php
+++ b/classes/pref/feeds.php
@@ -5,13 +5,16 @@ class Pref_Feeds extends Handler_Protected {
const E_ICON_UPLOAD_FAILED = 'E_ICON_UPLOAD_FAILED';
const E_ICON_UPLOAD_SUCCESS = 'E_ICON_UPLOAD_SUCCESS';
- function csrf_ignore($method) {
+ function csrf_ignore(string $method): bool {
$csrf_ignored = array("index", "getfeedtree", "savefeedorder");
return array_search($method, $csrf_ignored) !== false;
}
- public static function get_ts_languages() {
+ /**
+ * @return array<int, string>
+ */
+ public static function get_ts_languages(): array {
if (Config::get(Config::DB_TYPE) == 'pgsql') {
return array_map('ucfirst',
array_column(ORM::for_table('pg_ts_config')->select('cfgname')->find_array(), 'cfgname'));
@@ -20,7 +23,7 @@ class Pref_Feeds extends Handler_Protected {
return [];
}
- function renameCat() {
+ function renameCat(): void {
$cat = ORM::for_table("ttrss_feed_categories")
->where("owner_uid", $_SESSION["uid"])
->find_one($_REQUEST['id']);
@@ -33,7 +36,10 @@ class Pref_Feeds extends Handler_Protected {
}
}
- private function get_category_items($cat_id) {
+ /**
+ * @return array<int, array<string, bool|int|string>>
+ */
+ private function get_category_items(int $cat_id): array {
if (clean($_REQUEST['mode'] ?? 0) != 2)
$search = $_SESSION["prefs_feed_search"] ?? "";
@@ -103,11 +109,14 @@ class Pref_Feeds extends Handler_Protected {
return $items;
}
- function getfeedtree() {
+ function getfeedtree(): void {
print json_encode($this->_makefeedtree());
}
- function _makefeedtree() {
+ /**
+ * @return array<string, array<int|string, mixed>|string>
+ */
+ function _makefeedtree(): array {
if (clean($_REQUEST['mode'] ?? 0) != 2)
$search = $_SESSION["prefs_feed_search"] ?? "";
@@ -184,7 +193,7 @@ class Pref_Feeds extends Handler_Protected {
if (count($labels)) {
foreach ($labels as $label) {
$label_id = Labels::label_to_feed_id($label->id);
- $feed = $this->feedlist_init_feed($label_id, false, 0);
+ $feed = $this->feedlist_init_feed($label_id, null, false);
$feed['fg_color'] = $label->fg_color;
$feed['bg_color'] = $label->bg_color;
array_push($cat['items'], $feed);
@@ -319,19 +328,22 @@ class Pref_Feeds extends Handler_Protected {
];
}
- function catsortreset() {
+ function catsortreset(): void {
$sth = $this->pdo->prepare("UPDATE ttrss_feed_categories
SET order_id = 0 WHERE owner_uid = ?");
$sth->execute([$_SESSION['uid']]);
}
- function feedsortreset() {
+ function feedsortreset(): void {
$sth = $this->pdo->prepare("UPDATE ttrss_feeds
SET order_id = 0 WHERE owner_uid = ?");
$sth->execute([$_SESSION['uid']]);
}
- private function process_category_order(&$data_map, $item_id, $parent_id = false, $nest_level = 0) {
+ /**
+ * @param array<string, mixed> $data_map
+ */
+ private function process_category_order(array &$data_map, string $item_id = '', string $parent_id = '', int $nest_level = 0): void {
$prefix = "";
for ($i = 0; $i < $nest_level; $i++)
@@ -403,7 +415,7 @@ class Pref_Feeds extends Handler_Protected {
}
}
- function savefeedorder() {
+ function savefeedorder(): void {
$data = json_decode($_POST['payload'], true);
#file_put_contents("/tmp/saveorder.json", clean($_POST['payload']));
@@ -417,8 +429,9 @@ class Pref_Feeds extends Handler_Protected {
if (is_array($data) && is_array($data['items'])) {
# $cat_order_id = 0;
+ /** @var array<int, mixed> */
$data_map = array();
- $root_item = false;
+ $root_item = '';
foreach ($data['items'] as $item) {
@@ -439,7 +452,7 @@ class Pref_Feeds extends Handler_Protected {
}
}
- function removeIcon() {
+ function removeIcon(): void {
$feed_id = (int) $_REQUEST["feed_id"];
$icon_file = Config::get(Config::ICONS_DIR) . "/$feed_id.ico";
@@ -459,7 +472,7 @@ class Pref_Feeds extends Handler_Protected {
}
}
- function uploadIcon() {
+ function uploadIcon(): void {
$feed_id = (int) $_REQUEST['feed_id'];
$tmp_file = tempnam(Config::get(Config::CACHE_DIR) . '/upload', 'icon');
@@ -502,7 +515,7 @@ class Pref_Feeds extends Handler_Protected {
print json_encode(['rc' => $rc, 'icon_url' => Feeds::_get_icon($feed_id)]);
}
- function editfeed() {
+ function editfeed(): void {
global $purge_intervals;
global $update_intervals;
@@ -564,12 +577,12 @@ class Pref_Feeds extends Handler_Protected {
}
}
- private function _batch_toggle_checkbox($name) {
+ private function _batch_toggle_checkbox(string $name): string {
return \Controls\checkbox_tag("", false, "",
["data-control-for" => $name, "title" => __("Check to enable field"), "onchange" => "App.dialogOf(this).toggleField(this)"]);
}
- function editfeeds() {
+ function editfeeds(): void {
global $purge_intervals;
global $update_intervals;
@@ -677,15 +690,15 @@ class Pref_Feeds extends Handler_Protected {
<?php
}
- function batchEditSave() {
- return $this->editsaveops(true);
+ function batchEditSave(): void {
+ $this->editsaveops(true);
}
- function editSave() {
- return $this->editsaveops(false);
+ function editSave(): void {
+ $this->editsaveops(false);
}
- private function editsaveops($batch) {
+ private function editsaveops(bool $batch): void {
$feed_title = clean($_POST["title"]);
$feed_url = clean($_POST["feed_url"]);
@@ -774,11 +787,11 @@ class Pref_Feeds extends Handler_Protected {
break;
case "update_interval":
- $qpart = "update_interval = " . $this->pdo->quote($upd_intl);
+ $qpart = "update_interval = " . $upd_intl; // made int above
break;
case "purge_interval":
- $qpart = "purge_interval =" . $this->pdo->quote($purge_intl);
+ $qpart = "purge_interval = " . $purge_intl; // made int above
break;
case "auth_login":
@@ -790,33 +803,33 @@ class Pref_Feeds extends Handler_Protected {
break;
case "private":
- $qpart = "private = " . $this->pdo->quote($private);
+ $qpart = "private = " . $private; // made int above
break;
case "include_in_digest":
- $qpart = "include_in_digest = " . $this->pdo->quote($include_in_digest);
+ $qpart = "include_in_digest = " . $include_in_digest; // made int above
break;
case "always_display_enclosures":
- $qpart = "always_display_enclosures = " . $this->pdo->quote($always_display_enclosures);
+ $qpart = "always_display_enclosures = " . $always_display_enclosures; // made int above
break;
case "mark_unread_on_update":
- $qpart = "mark_unread_on_update = " . $this->pdo->quote($mark_unread_on_update);
+ $qpart = "mark_unread_on_update = " . $mark_unread_on_update; // made int above
break;
case "cache_images":
- $qpart = "cache_images = " . $this->pdo->quote($cache_images);
+ $qpart = "cache_images = " . $cache_images; // made int above
break;
case "hide_images":
- $qpart = "hide_images = " . $this->pdo->quote($hide_images);
+ $qpart = "hide_images = " . $hide_images; // made int above
break;
case "cat_id":
if (get_pref(Prefs::ENABLE_FEED_CATS)) {
if ($cat_id) {
- $qpart = "cat_id = " . $this->pdo->quote($cat_id);
+ $qpart = "cat_id = " . $cat_id; // made int above
} else {
$qpart = 'cat_id = NULL';
}
@@ -841,39 +854,36 @@ class Pref_Feeds extends Handler_Protected {
$this->pdo->commit();
}
- return;
}
- function remove() {
-
- $ids = explode(",", clean($_REQUEST["ids"]));
+ function remove(): void {
+ /** @var array<int, int> */
+ $ids = array_map('intval', explode(",", clean($_REQUEST["ids"])));
foreach ($ids as $id) {
self::remove_feed($id, $_SESSION["uid"]);
}
-
- return;
}
- function removeCat() {
+ function removeCat(): void {
$ids = explode(",", clean($_REQUEST["ids"]));
foreach ($ids as $id) {
Feeds::_remove_cat((int)$id, $_SESSION["uid"]);
}
}
- function addCat() {
+ function addCat(): void {
$feed_cat = clean($_REQUEST["cat"]);
Feeds::_add_cat($feed_cat, $_SESSION['uid']);
}
- function importOpml() {
+ function importOpml(): void {
$opml = new OPML($_REQUEST);
$opml->opml_import($_SESSION["uid"]);
}
- private function index_feeds() {
+ private function index_feeds(): void {
$error_button = "<button dojoType='dijit.form.Button'
id='pref_feeds_errors_btn' style='display : none'
onclick='CommonDialogs.showFeedsWithErrors()'>".
@@ -984,7 +994,7 @@ class Pref_Feeds extends Handler_Protected {
}
- private function index_opml() {
+ private function index_opml(): void {
?>
<form id='opml_import_form' method='post' enctype='multipart/form-data'>
@@ -1020,7 +1030,7 @@ class Pref_Feeds extends Handler_Protected {
PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, "prefFeedsOPML");
}
- private function index_shared() {
+ private function index_shared(): void {
?>
<?= format_notice('Published articles can be subscribed by anyone who knows the following URL:') ?></h3>
@@ -1040,7 +1050,7 @@ class Pref_Feeds extends Handler_Protected {
PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, "prefFeedsPublishedGenerated");
}
- function index() {
+ function index(): void {
?>
<div dojoType='dijit.layout.TabContainer' tabPosition='left-h'>
@@ -1079,44 +1089,44 @@ class Pref_Feeds extends Handler_Protected {
<?php
}
- private function feedlist_init_cat($cat_id) {
- $obj = array();
- $cat_id = (int) $cat_id;
-
- $obj['id'] = 'CAT:' . $cat_id;
- $obj['items'] = array();
- $obj['name'] = Feeds::_get_cat_title($cat_id);
- $obj['type'] = 'category';
- $obj['unread'] = -1; //(int) Feeds::_get_cat_unread($cat_id);
- $obj['bare_id'] = $cat_id;
-
- return $obj;
+ /**
+ * @return array<string, mixed>
+ */
+ private function feedlist_init_cat(int $cat_id): array {
+ return [
+ 'id' => 'CAT:' . $cat_id,
+ 'items' => array(),
+ 'name' => Feeds::_get_cat_title($cat_id),
+ 'type' => 'category',
+ 'unread' => -1, //(int) Feeds::_get_cat_unread($cat_id);
+ 'bare_id' => $cat_id,
+ ];
}
- private function feedlist_init_feed($feed_id, $title = false, $unread = false, $error = '', $updated = '') {
- $obj = array();
- $feed_id = (int) $feed_id;
-
+ /**
+ * @return array<string, mixed>
+ */
+ private function feedlist_init_feed(int $feed_id, ?string $title = null, bool $unread = false, string $error = '', string $updated = ''): array {
if (!$title)
$title = Feeds::_get_title($feed_id, false);
if ($unread === false)
$unread = getFeedUnread($feed_id, false);
- $obj['id'] = 'FEED:' . $feed_id;
- $obj['name'] = $title;
- $obj['unread'] = (int) $unread;
- $obj['type'] = 'feed';
- $obj['error'] = $error;
- $obj['updated'] = $updated;
- $obj['icon'] = Feeds::_get_icon($feed_id);
- $obj['bare_id'] = $feed_id;
- $obj['auxcounter'] = 0;
-
- return $obj;
+ return [
+ 'id' => 'FEED:' . $feed_id,
+ 'name' => $title,
+ 'unread' => (int) $unread,
+ 'type' => 'feed',
+ 'error' => $error,
+ 'updated' => $updated,
+ 'icon' => Feeds::_get_icon($feed_id),
+ 'bare_id' => $feed_id,
+ 'auxcounter' => 0,
+ ];
}
- function inactiveFeeds() {
+ function inactiveFeeds(): void {
if (Config::get(Config::DB_TYPE) == "pgsql") {
$interval_qpart = "NOW() - INTERVAL '3 months'";
@@ -1150,7 +1160,7 @@ class Pref_Feeds extends Handler_Protected {
print json_encode($inactive_feeds);
}
- function feedsWithErrors() {
+ function feedsWithErrors(): void {
print json_encode(ORM::for_table('ttrss_feeds')
->select_many('id', 'title', 'feed_url', 'last_error', 'site_url')
->where_not_equal('last_error', '')
@@ -1158,7 +1168,7 @@ class Pref_Feeds extends Handler_Protected {
->find_array());
}
- static function remove_feed($id, $owner_uid) {
+ static function remove_feed(int $id, int $owner_uid): void {
if (PluginHost::getInstance()->run_hooks_until(PluginHost::HOOK_UNSUBSCRIBE_FEED, true, $id, $owner_uid))
return;
@@ -1199,14 +1209,14 @@ class Pref_Feeds extends Handler_Protected {
}
}
- function batchSubscribe() {
+ function batchSubscribe(): void {
print json_encode([
"enable_cats" => (int)get_pref(Prefs::ENABLE_FEED_CATS),
"cat_select" => \Controls\select_feeds_cats("cat")
]);
}
- function batchAddFeeds() {
+ function batchAddFeeds(): void {
$cat_id = clean($_REQUEST['cat']);
$feeds = explode("\n", clean($_REQUEST['feeds']));
$login = clean($_REQUEST['login']);
@@ -1216,7 +1226,7 @@ class Pref_Feeds extends Handler_Protected {
// TODO: we should return some kind of error code to frontend here
if ($user->access_level == UserHelper::ACCESS_LEVEL_READONLY) {
- return false;
+ return;
}
$csth = $this->pdo->prepare("SELECT id FROM ttrss_feeds
@@ -1244,11 +1254,11 @@ class Pref_Feeds extends Handler_Protected {
}
}
- function clearKeys() {
- return Feeds::_clear_access_keys($_SESSION['uid']);
+ function clearKeys(): void {
+ Feeds::_clear_access_keys($_SESSION['uid']);
}
- function regenFeedKey() {
+ function regenFeedKey(): void {
$feed_id = clean($_REQUEST['id']);
$is_cat = clean($_REQUEST['is_cat']);
@@ -1257,7 +1267,7 @@ class Pref_Feeds extends Handler_Protected {
print json_encode(["link" => $new_key]);
}
- function getSharedURL() {
+ function getSharedURL(): void {
$feed_id = clean($_REQUEST['id']);
$is_cat = clean($_REQUEST['is_cat']) == "true";
$search = clean($_REQUEST['search']);
@@ -1276,7 +1286,10 @@ class Pref_Feeds extends Handler_Protected {
]);
}
- private function calculate_children_count($cat) {
+ /**
+ * @param array<string, mixed> $cat
+ */
+ private function calculate_children_count(array $cat): int {
$c = 0;
foreach ($cat['items'] ?? [] as $child) {
diff --git a/classes/pref/filters.php b/classes/pref/filters.php
index c4017e4ec..6e6e3d9ee 100755
--- a/classes/pref/filters.php
+++ b/classes/pref/filters.php
@@ -1,20 +1,19 @@
<?php
class Pref_Filters extends Handler_Protected {
- function csrf_ignore($method) {
+ function csrf_ignore(string $method): bool {
$csrf_ignored = array("index", "getfiltertree", "savefilterorder");
return array_search($method, $csrf_ignored) !== false;
}
- function filtersortreset() {
+ function filtersortreset(): void {
$sth = $this->pdo->prepare("UPDATE ttrss_filters2
SET order_id = 0 WHERE owner_uid = ?");
$sth->execute([$_SESSION['uid']]);
- return;
}
- function savefilterorder() {
+ function savefilterorder(): void {
$data = json_decode($_POST['payload'], true);
#file_put_contents("/tmp/saveorder.json", clean($_POST['payload']));
@@ -40,11 +39,9 @@ class Pref_Filters extends Handler_Protected {
}
}
}
-
- return;
}
- function testFilterDo() {
+ function testFilterDo(): void {
$offset = (int) clean($_REQUEST["offset"]);
$limit = (int) clean($_REQUEST["limit"]);
@@ -59,7 +56,9 @@ class Pref_Filters extends Handler_Protected {
$res = $this->pdo->query("SELECT id,name FROM ttrss_filter_types");
- $filter_types = array();
+ /** @var array<int, string> */
+ $filter_types = [];
+
while ($line = $res->fetch()) {
$filter_types[$line["id"]] = $line["name"];
}
@@ -67,7 +66,10 @@ class Pref_Filters extends Handler_Protected {
$scope_qparts = array();
$rctr = 0;
+
+ /** @var string $r */
foreach (clean($_REQUEST["rule"]) AS $r) {
+ /** @var array{'reg_exp': string, 'filter_type': int, 'feed_id': array<int, int|string>, 'name': string}|null */
$rule = json_decode($r, true);
if ($rule && $rctr < 5) {
@@ -75,19 +77,21 @@ class Pref_Filters extends Handler_Protected {
unset($rule["filter_type"]);
$scope_inner_qparts = [];
+
+ /** @var int|string $feed_id may be a category string (e.g. 'CAT:7') or feed ID int */
foreach ($rule["feed_id"] as $feed_id) {
- if (strpos($feed_id, "CAT:") === 0) {
- $cat_id = (int) substr($feed_id, 4);
- array_push($scope_inner_qparts, "cat_id = " . $this->pdo->quote($cat_id));
- } else if ($feed_id > 0) {
- array_push($scope_inner_qparts, "feed_id = " . $this->pdo->quote($feed_id));
- }
- }
+ if (strpos("$feed_id", "CAT:") === 0) {
+ $cat_id = (int) substr("$feed_id", 4);
+ array_push($scope_inner_qparts, "cat_id = " . $cat_id);
+ } else if (is_numeric($feed_id) && $feed_id > 0) {
+ array_push($scope_inner_qparts, "feed_id = " . (int)$feed_id);
+ }
+ }
- if (count($scope_inner_qparts) > 0) {
- array_push($scope_qparts, "(" . implode(" OR ", $scope_inner_qparts) . ")");
- }
+ if (count($scope_inner_qparts) > 0) {
+ array_push($scope_qparts, "(" . implode(" OR ", $scope_inner_qparts) . ")");
+ }
array_push($filter["rules"], $rule);
@@ -162,7 +166,7 @@ class Pref_Filters extends Handler_Protected {
print json_encode($rv);
}
- private function _get_rules_list($filter_id) {
+ private function _get_rules_list(int $filter_id): string {
$sth = $this->pdo->prepare("SELECT reg_exp,
inverse,
match_on,
@@ -222,7 +226,7 @@ class Pref_Filters extends Handler_Protected {
return $rv;
}
- function getfiltertree() {
+ function getfiltertree(): void {
$root = array();
$root['id'] = 'root';
$root['name'] = __('Filters');
@@ -307,10 +311,9 @@ class Pref_Filters extends Handler_Protected {
$fl['items'] = array($root);
print json_encode($fl);
- return;
}
- function edit() {
+ function edit(): void {
$filter_id = (int) clean($_REQUEST["id"] ?? 0);
@@ -406,7 +409,10 @@ class Pref_Filters extends Handler_Protected {
}
}
- private function _get_rule_name($rule) {
+ /**
+ * @param array<string, mixed>|null $rule
+ */
+ private function _get_rule_name(?array $rule = null): string {
if (!$rule) $rule = json_decode(clean($_REQUEST["rule"]), true);
$feeds = $rule["feed_id"];
@@ -446,11 +452,18 @@ class Pref_Filters extends Handler_Protected {
"<span class='field'>$filter_type</span>", "<span class='feed'>$feed</span>", isset($rule["inverse"]) ? __("(inverse)") : "") . "</span>";
}
- function printRuleName() {
+ function printRuleName(): void {
print $this->_get_rule_name(json_decode(clean($_REQUEST["rule"]), true));
}
- private function _get_action_name($action) {
+ /**
+ * @param array<string, mixed>|null $action
+ */
+ private function _get_action_name(?array $action = null): string {
+ if (!$action) {
+ return "";
+ }
+
$sth = $this->pdo->prepare("SELECT description FROM
ttrss_filter_actions WHERE id = ?");
$sth->execute([(int)$action["action_id"]]);
@@ -484,12 +497,12 @@ class Pref_Filters extends Handler_Protected {
return $title;
}
- function printActionName() {
- print $this->_get_action_name(json_decode(clean($_REQUEST["action"]), true));
+ function printActionName(): void {
+ print $this->_get_action_name(json_decode(clean($_REQUEST["action"] ?? ""), true));
}
- function editSave() {
- $filter_id = clean($_REQUEST["id"]);
+ function editSave(): void {
+ $filter_id = (int) clean($_REQUEST["id"]);
$enabled = checkbox_to_sql_bool(clean($_REQUEST["enabled"] ?? false));
$match_any_rule = checkbox_to_sql_bool(clean($_REQUEST["match_any_rule"] ?? false));
$inverse = checkbox_to_sql_bool(clean($_REQUEST["inverse"] ?? false));
@@ -510,7 +523,7 @@ class Pref_Filters extends Handler_Protected {
$this->pdo->commit();
}
- function remove() {
+ function remove(): void {
$ids = explode(",", clean($_REQUEST["ids"]));
$ids_qmarks = arr_qmarks($ids);
@@ -520,7 +533,7 @@ class Pref_Filters extends Handler_Protected {
$sth->execute(array_merge($ids, [$_SESSION['uid']]));
}
- private function _save_rules_and_actions($filter_id) {
+ private function _save_rules_and_actions(int $filter_id): void {
$sth = $this->pdo->prepare("DELETE FROM ttrss_filters2_rules WHERE filter_id = ?");
$sth->execute([$filter_id]);
@@ -597,7 +610,7 @@ class Pref_Filters extends Handler_Protected {
}
}
- function add () {
+ function add(): void {
$enabled = checkbox_to_sql_bool(clean($_REQUEST["enabled"] ?? false));
$match_any_rule = checkbox_to_sql_bool(clean($_REQUEST["match_any_rule"] ?? false));
$title = clean($_REQUEST["title"]);
@@ -625,7 +638,7 @@ class Pref_Filters extends Handler_Protected {
$this->pdo->commit();
}
- function index() {
+ function index(): void {
if (array_key_exists("search", $_REQUEST)) {
$filter_search = clean($_REQUEST["search"]);
$_SESSION["prefs_filter_search"] = $filter_search;
@@ -691,7 +704,8 @@ class Pref_Filters extends Handler_Protected {
<?php
}
- function editrule() {
+ function editrule(): void {
+ /** @var array<int, int|string> */
$feed_ids = explode(",", clean($_REQUEST["ids"]));
print json_encode([
@@ -699,7 +713,10 @@ class Pref_Filters extends Handler_Protected {
]);
}
- private function _get_name($id) {
+ /**
+ * @return array<int, string>
+ */
+ private function _get_name(int $id): array {
$sth = $this->pdo->prepare(
"SELECT title,match_any_rule,f.inverse AS inverse,COUNT(DISTINCT r.id) AS num_rules,COUNT(DISTINCT a.id) AS num_actions
@@ -745,8 +762,9 @@ class Pref_Filters extends Handler_Protected {
return [];
}
- function join() {
- $ids = explode(",", clean($_REQUEST["ids"]));
+ function join(): void {
+ /** @var array<int, int> */
+ $ids = array_map("intval", explode(",", clean($_REQUEST["ids"])));
if (count($ids) > 1) {
$base_id = array_shift($ids);
@@ -775,7 +793,7 @@ class Pref_Filters extends Handler_Protected {
}
}
- private function _optimize($id) {
+ private function _optimize(int $id): void {
$this->pdo->beginTransaction();
@@ -830,9 +848,11 @@ class Pref_Filters extends Handler_Protected {
$this->pdo->commit();
}
- private function _feed_multi_select($id, $default_ids = [],
- $attributes = "", $include_all_feeds = true,
- $root_id = null, $nest_level = 0) {
+ /**
+ * @param array<int, int|string> $default_ids
+ */
+ private function _feed_multi_select(string $id, array $default_ids = [], string $attributes = "",
+ bool $include_all_feeds = true, ?int $root_id = null, int $nest_level = 0): string {
$pdo = Db::pdo();
diff --git a/classes/pref/labels.php b/classes/pref/labels.php
index 0eb88ea36..a50a85a66 100644
--- a/classes/pref/labels.php
+++ b/classes/pref/labels.php
@@ -1,13 +1,13 @@
<?php
class Pref_Labels extends Handler_Protected {
- function csrf_ignore($method) {
+ function csrf_ignore(string $method): bool {
$csrf_ignored = array("index", "getlabeltree");
return array_search($method, $csrf_ignored) !== false;
}
- function edit() {
+ function edit(): void {
$label = ORM::for_table('ttrss_labels2')
->where('owner_uid', $_SESSION['uid'])
->find_one($_REQUEST['id']);
@@ -17,7 +17,7 @@ class Pref_Labels extends Handler_Protected {
}
}
- function getlabeltree() {
+ function getlabeltree(): void {
$root = array();
$root['id'] = 'root';
$root['name'] = __('Labels');
@@ -48,10 +48,9 @@ class Pref_Labels extends Handler_Protected {
$fl['items'] = array($root);
print json_encode($fl);
- return;
}
- function colorset() {
+ function colorset(): void {
$kind = clean($_REQUEST["kind"]);
$ids = explode(',', clean($_REQUEST["ids"]));
$color = clean($_REQUEST["color"]);
@@ -84,7 +83,7 @@ class Pref_Labels extends Handler_Protected {
}
}
- function colorreset() {
+ function colorreset(): void {
$ids = explode(',', clean($_REQUEST["ids"]));
foreach ($ids as $id) {
@@ -101,7 +100,7 @@ class Pref_Labels extends Handler_Protected {
}
}
- function save() {
+ function save(): void {
$id = clean($_REQUEST["id"]);
$caption = clean($_REQUEST["caption"]);
@@ -148,9 +147,9 @@ class Pref_Labels extends Handler_Protected {
}
- function remove() {
-
- $ids = explode(",", clean($_REQUEST["ids"]));
+ function remove(): void {
+ /** @var array<int, int> */
+ $ids = array_map("intval", explode(",", clean($_REQUEST["ids"])));
foreach ($ids as $id) {
Labels::remove($id, $_SESSION["uid"]);
@@ -158,7 +157,7 @@ class Pref_Labels extends Handler_Protected {
}
- function add() {
+ function add(): void {
$caption = clean($_REQUEST["caption"]);
$output = clean($_REQUEST["output"] ?? false);
@@ -171,7 +170,7 @@ class Pref_Labels extends Handler_Protected {
}
}
- function index() {
+ function index(): void {
?>
<div dojoType='dijit.layout.BorderContainer' gutters='false'>
<div style='padding : 0px' dojoType='dijit.layout.ContentPane' region='top'>
diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php
index c45d6d6ea..d3a5a1370 100644
--- a/classes/pref/prefs.php
+++ b/classes/pref/prefs.php
@@ -2,12 +2,21 @@
use chillerlan\QRCode;
class Pref_Prefs extends Handler_Protected {
-
+ // TODO: class properties can be switched to PHP typing if/when the minimum PHP_VERSION is raised to 7.4.0+
+ /** @var array<Prefs::*, array<int, string>> */
private $pref_help = [];
+
+ /** @var array<string, array<int, string>> pref items are Prefs::*|Pref_Prefs::BLOCK_SEPARATOR (PHPStan was complaining) */
private $pref_item_map = [];
+
+ /** @var array<string, string> */
private $pref_help_bottom = [];
+
+ /** @var array<int, string> */
private $pref_blacklist = [];
+ private const BLOCK_SEPARATOR = 'BLOCK_SEPARATOR';
+
const PI_RES_ALREADY_INSTALLED = "PI_RES_ALREADY_INSTALLED";
const PI_RES_SUCCESS = "PI_RES_SUCCESS";
const PI_ERR_NO_CLASS = "PI_ERR_NO_CLASS";
@@ -17,7 +26,8 @@ class Pref_Prefs extends Handler_Protected {
const PI_ERR_PLUGIN_NOT_FOUND = "PI_ERR_PLUGIN_NOT_FOUND";
const PI_ERR_NO_WORKDIR = "PI_ERR_NO_WORKDIR";
- function csrf_ignore($method) {
+ /** @param string $method */
+ function csrf_ignore($method) : bool {
$csrf_ignored = array("index", "updateself", "otpqrcode");
return array_search($method, $csrf_ignored) !== false;
@@ -30,35 +40,35 @@ class Pref_Prefs extends Handler_Protected {
__('General') => [
Prefs::USER_LANGUAGE,
Prefs::USER_TIMEZONE,
- 'BLOCK_SEPARATOR',
+ self::BLOCK_SEPARATOR,
Prefs::USER_CSS_THEME,
- 'BLOCK_SEPARATOR',
+ self::BLOCK_SEPARATOR,
Prefs::ENABLE_API_ACCESS,
],
__('Feeds') => [
Prefs::DEFAULT_UPDATE_INTERVAL,
Prefs::FRESH_ARTICLE_MAX_AGE,
Prefs::DEFAULT_SEARCH_LANGUAGE,
- 'BLOCK_SEPARATOR',
+ self::BLOCK_SEPARATOR,
Prefs::ENABLE_FEED_CATS,
- 'BLOCK_SEPARATOR',
+ self::BLOCK_SEPARATOR,
Prefs::CONFIRM_FEED_CATCHUP,
Prefs::ON_CATCHUP_SHOW_NEXT_FEED,
- 'BLOCK_SEPARATOR',
+ self::BLOCK_SEPARATOR,
Prefs::HIDE_READ_FEEDS,
Prefs::HIDE_READ_SHOWS_SPECIAL,
],
__('Articles') => [
Prefs::PURGE_OLD_DAYS,
Prefs::PURGE_UNREAD_ARTICLES,
- 'BLOCK_SEPARATOR',
+ self::BLOCK_SEPARATOR,
Prefs::COMBINED_DISPLAY_MODE,
Prefs::CDM_EXPANDED,
Prefs::CDM_ENABLE_GRID,
- 'BLOCK_SEPARATOR',
+ self::BLOCK_SEPARATOR,
Prefs::CDM_AUTO_CATCHUP,
Prefs::VFEED_GROUP_BY_FEED,
- 'BLOCK_SEPARATOR',
+ self::BLOCK_SEPARATOR,
Prefs::SHOW_CONTENT_PREVIEW,
Prefs::STRIP_IMAGES,
],
@@ -69,12 +79,12 @@ class Pref_Prefs extends Handler_Protected {
],
__('Advanced') => [
Prefs::BLACKLISTED_TAGS,
- 'BLOCK_SEPARATOR',
+ self::BLOCK_SEPARATOR,
Prefs::LONG_DATE_FORMAT,
Prefs::SHORT_DATE_FORMAT,
- 'BLOCK_SEPARATOR',
+ self::BLOCK_SEPARATOR,
Prefs::SSL_CERT_SERIAL,
- 'BLOCK_SEPARATOR',
+ self::BLOCK_SEPARATOR,
Prefs::DISABLE_CONDITIONAL_COUNTERS,
Prefs::HEADLINES_NO_DISTINCT,
],
@@ -127,7 +137,7 @@ class Pref_Prefs extends Handler_Protected {
];
}
- function changepassword() {
+ function changepassword(): void {
if (Config::get(Config::FORBID_PASSWORD_CHANGES)) {
print "ERROR: ".format_error("Access forbidden.");
@@ -173,7 +183,7 @@ class Pref_Prefs extends Handler_Protected {
}
}
- function saveconfig() {
+ function saveconfig(): void {
$boolean_prefs = explode(",", clean($_POST["boolean_prefs"]));
foreach ($boolean_prefs as $pref) {
@@ -223,7 +233,7 @@ class Pref_Prefs extends Handler_Protected {
}
}
- function changePersonalData() {
+ function changePersonalData(): void {
$user = ORM::for_table('ttrss_users')->find_one($_SESSION['uid']);
$new_email = clean($_POST['email']);
@@ -264,13 +274,13 @@ class Pref_Prefs extends Handler_Protected {
print __("Your personal data has been saved.");
}
- function resetconfig() {
+ function resetconfig(): void {
Prefs::reset($_SESSION["uid"], $_SESSION["profile"]);
print "PREFS_NEED_RELOAD";
}
- private function index_auth_personal() {
+ private function index_auth_personal(): void {
$user = ORM::for_table('ttrss_users')->find_one($_SESSION['uid']);
@@ -310,7 +320,7 @@ class Pref_Prefs extends Handler_Protected {
<?php
}
- private function index_auth_password() {
+ private function index_auth_password(): void {
if ($_SESSION["auth_module"]) {
$authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
} else {
@@ -385,7 +395,7 @@ class Pref_Prefs extends Handler_Protected {
}
}
- private function index_auth_app_passwords() {
+ private function index_auth_app_passwords(): void {
print_notice("Separate passwords used for API clients. Required if you enable OTP.");
?>
@@ -409,7 +419,7 @@ class Pref_Prefs extends Handler_Protected {
<?php
}
- private function index_auth_2fa() {
+ private function index_auth_2fa(): void {
$otp_enabled = UserHelper::is_otp_enabled($_SESSION["uid"]);
if ($_SESSION["auth_module"] == "auth_internal") {
@@ -515,7 +525,7 @@ class Pref_Prefs extends Handler_Protected {
}
}
- function index_auth() {
+ function index_auth(): void {
?>
<div dojoType='dijit.layout.TabContainer'>
<div dojoType='dijit.layout.ContentPane' title="<?= __('Personal data') ?>">
@@ -534,35 +544,38 @@ class Pref_Prefs extends Handler_Protected {
<?php
}
- private function index_prefs_list() {
+ private function index_prefs_list(): void {
$profile = $_SESSION["profile"] ?? null;
if ($profile) {
print_notice(__("Some preferences are only available in default profile."));
}
+ /** @var array<string, array{'type_hint': Config::T_*, 'value': bool|int|string, 'help_text': string, 'short_desc': string}> */
$prefs_available = [];
+
+ /** @var array<int, string> */
$listed_boolean_prefs = [];
- foreach (Prefs::get_all($_SESSION["uid"], $profile) as $line) {
+ foreach (Prefs::get_all($_SESSION["uid"], $profile) as $pref) {
- if (in_array($line["pref_name"], $this->pref_blacklist)) {
+ if (in_array($pref["pref_name"], $this->pref_blacklist)) {
continue;
}
- if ($profile && in_array($line["pref_name"], Prefs::_PROFILE_BLACKLIST)) {
+ if ($profile && in_array($pref["pref_name"], Prefs::_PROFILE_BLACKLIST)) {
continue;
}
- $pref_name = $line["pref_name"];
+ $pref_name = $pref["pref_name"];
$short_desc = $this->_get_short_desc($pref_name);
if (!$short_desc)
continue;
$prefs_available[$pref_name] = [
- 'type_hint' => $line['type_hint'],
- 'value' => $line['value'],
+ 'type_hint' => $pref['type_hint'],
+ 'value' => $pref['value'],
'help_text' => $this->_get_help_text($pref_name),
'short_desc' => $short_desc
];
@@ -574,12 +587,12 @@ class Pref_Prefs extends Handler_Protected {
foreach ($this->pref_item_map[$section] as $pref_name) {
- if ($pref_name == 'BLOCK_SEPARATOR' && !$profile) {
+ if ($pref_name == self::BLOCK_SEPARATOR && !$profile) {
print "<hr/>";
continue;
}
- if ($pref_name == "DEFAULT_SEARCH_LANGUAGE" && Config::get(Config::DB_TYPE) != "pgsql") {
+ if ($pref_name == Prefs::DEFAULT_SEARCH_LANGUAGE && Config::get(Config::DB_TYPE) != "pgsql") {
continue;
}
@@ -596,17 +609,17 @@ class Pref_Prefs extends Handler_Protected {
$value = $item['value'];
$type_hint = $item['type_hint'];
- if ($pref_name == "USER_LANGUAGE") {
+ if ($pref_name == Prefs::USER_LANGUAGE) {
print \Controls\select_hash($pref_name, $value, get_translations(),
["style" => 'width : 220px; margin : 0px']);
- } else if ($pref_name == "USER_TIMEZONE") {
+ } else if ($pref_name == Prefs::USER_TIMEZONE) {
$timezones = explode("\n", file_get_contents("lib/timezones.txt"));
print \Controls\select_tag($pref_name, $value, $timezones, ["dojoType" => "dijit.form.FilteringSelect"]);
- } else if ($pref_name == "BLACKLISTED_TAGS") { # TODO: other possible <textarea> prefs go here
+ } else if ($pref_name == Prefs::BLACKLISTED_TAGS) { # TODO: other possible <textarea> prefs go here
print "<div>";
@@ -618,7 +631,7 @@ class Pref_Prefs extends Handler_Protected {
print "</div>";
- } else if ($pref_name == "USER_CSS_THEME") {
+ } else if ($pref_name == Prefs::USER_CSS_THEME) {
$theme_files = array_map("basename",
array_merge(glob("themes/*.php"),
@@ -642,13 +655,13 @@ class Pref_Prefs extends Handler_Protected {
<?php
- } else if ($pref_name == "DEFAULT_UPDATE_INTERVAL") {
+ } else if ($pref_name == Prefs::DEFAULT_UPDATE_INTERVAL) {
global $update_intervals_nodefault;
print \Controls\select_hash($pref_name, $value, $update_intervals_nodefault);
- } else if ($pref_name == "DEFAULT_SEARCH_LANGUAGE") {
+ } else if ($pref_name == Prefs::DEFAULT_SEARCH_LANGUAGE) {
print \Controls\select_tag($pref_name, $value, Pref_Feeds::get_ts_languages());
@@ -656,7 +669,7 @@ class Pref_Prefs extends Handler_Protected {
array_push($listed_boolean_prefs, $pref_name);
- if ($pref_name == "PURGE_UNREAD_ARTICLES" && Config::get(Config::FORCE_ARTICLE_PURGE) != 0) {
+ if ($pref_name == Prefs::PURGE_UNREAD_ARTICLES && Config::get(Config::FORCE_ARTICLE_PURGE) != 0) {
$is_disabled = true;
$is_checked = true;
} else {
@@ -672,10 +685,10 @@ class Pref_Prefs extends Handler_Protected {
['onclick' => 'Helpers.Digest.preview()', 'style' => 'margin-left : 10px']);
}
- } else if (in_array($pref_name, ['FRESH_ARTICLE_MAX_AGE',
- 'PURGE_OLD_DAYS', 'LONG_DATE_FORMAT', 'SHORT_DATE_FORMAT'])) {
+ } else if (in_array($pref_name, [Prefs::FRESH_ARTICLE_MAX_AGE,
+ Prefs::PURGE_OLD_DAYS, Prefs::LONG_DATE_FORMAT, Prefs::SHORT_DATE_FORMAT])) {
- if ($pref_name == "PURGE_OLD_DAYS" && Config::get(Config::FORCE_ARTICLE_PURGE) != 0) {
+ if ($pref_name == Prefs::PURGE_OLD_DAYS && Config::get(Config::FORCE_ARTICLE_PURGE) != 0) {
$attributes = ["disabled" => true, "required" => true];
$value = Config::get(Config::FORCE_ARTICLE_PURGE);
} else {
@@ -687,7 +700,7 @@ class Pref_Prefs extends Handler_Protected {
else
print \Controls\input_tag($pref_name, $value, "text", $attributes);
- } else if ($pref_name == "SSL_CERT_SERIAL") {
+ } else if ($pref_name == Prefs::SSL_CERT_SERIAL) {
print \Controls\input_tag($pref_name, $value, "text", ["readonly" => true], "SSL_CERT_SERIAL");
@@ -727,7 +740,7 @@ class Pref_Prefs extends Handler_Protected {
print \Controls\hidden_tag("boolean_prefs", htmlspecialchars(join(",", $listed_boolean_prefs)));
}
- private function index_prefs() {
+ private function index_prefs(): void {
?>
<form dojoType='dijit.form.Form' id='changeSettingsForm'>
<?= \Controls\hidden_tag("op", "pref-prefs") ?>
@@ -783,7 +796,7 @@ class Pref_Prefs extends Handler_Protected {
<?php
}
- function getPluginsList() {
+ function getPluginsList(): void {
$system_enabled = array_map("trim", explode(",", (string)Config::get(Config::PLUGINS)));
$user_enabled = array_map("trim", explode(",", get_pref(Prefs::_ENABLED_PLUGINS)));
@@ -816,7 +829,7 @@ class Pref_Prefs extends Handler_Protected {
print json_encode(['plugins' => $rv, 'is_admin' => $_SESSION['access_level'] >= UserHelper::ACCESS_LEVEL_ADMIN]);
}
- function index_plugins() {
+ function index_plugins(): void {
?>
<form dojoType="dijit.form.Form" id="changePluginsForm">
@@ -912,7 +925,7 @@ class Pref_Prefs extends Handler_Protected {
<?php
}
- function index() {
+ function index(): void {
?>
<div dojoType='dijit.layout.AccordionContainer' region='center'>
<div dojoType='dijit.layout.AccordionPane' title="<i class='material-icons'>person</i> <?= __('Personal data / Authentication')?>">
@@ -937,7 +950,7 @@ class Pref_Prefs extends Handler_Protected {
<?php
}
- function _get_otp_qrcode_img() {
+ function _get_otp_qrcode_img(): ?string {
$secret = UserHelper::get_otp_secret($_SESSION["uid"]);
$login = UserHelper::get_login_by_id($_SESSION["uid"]);
@@ -949,15 +962,16 @@ class Pref_Prefs extends Handler_Protected {
return $qrcode->render($otpurl);
}
- return false;
+ return null;
}
- function otpenable() {
+ function otpenable(): void {
$password = clean($_REQUEST["password"]);
$otp_check = clean($_REQUEST["otp"]);
$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 */
if ($authenticator->check_password($_SESSION["uid"], $password)) {
if (UserHelper::enable_otp($_SESSION["uid"], $otp_check)) {
print "OK";
@@ -969,9 +983,10 @@ class Pref_Prefs extends Handler_Protected {
}
}
- function otpdisable() {
+ function otpdisable(): void {
$password = clean($_REQUEST["password"]);
+ /** @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->check_password($_SESSION["uid"], $password)) {
@@ -1008,38 +1023,42 @@ class Pref_Prefs extends Handler_Protected {
}
- function setplugins() {
+ function setplugins(): void {
$plugins = array_filter($_REQUEST["plugins"], 'clean') ?? [];
set_pref(Prefs::_ENABLED_PLUGINS, implode(",", $plugins));
}
- function _get_plugin_version(Plugin $plugin) {
+ function _get_plugin_version(Plugin $plugin): string {
$about = $plugin->about();
if (!empty($about[0])) {
return T_sprintf("v%.2f, by %s", $about[0], $about[2]);
- } else {
- $ref = new ReflectionClass(get_class($plugin));
+ }
- $plugin_dir = dirname($ref->getFileName());
+ $ref = new ReflectionClass(get_class($plugin));
- if (basename($plugin_dir) == "plugins") {
- return "";
- }
+ $plugin_dir = dirname($ref->getFileName());
- if (is_dir("$plugin_dir/.git")) {
- $ver = Config::get_version_from_git($plugin_dir);
+ if (basename($plugin_dir) == "plugins") {
+ return "";
+ }
- return $ver["status"] == 0 ? T_sprintf("v%s, by %s", $ver["version"], $about[2]) : $ver["version"];
- }
+ if (is_dir("$plugin_dir/.git")) {
+ $ver = Config::get_version_from_git($plugin_dir);
+
+ return $ver["status"] == 0 ? T_sprintf("v%s, by %s", $ver["version"], $about[2]) : $ver["version"];
}
+
+ return "";
}
- static function _get_updated_plugins() {
+ /**
+ * @return array<int, array{'plugin': string, 'rv': array{'stdout': false|string, 'stderr': false|string, 'git_status': int, 'need_update': bool}|null}>
+ */
+ static function _get_updated_plugins(): array {
$root_dir = dirname(dirname(__DIR__)); # we're in classes/pref/
$plugin_dirs = array_filter(glob("$root_dir/plugins.local/*"), "is_dir");
-
$rv = [];
foreach ($plugin_dirs as $dir) {
@@ -1057,7 +1076,10 @@ class Pref_Prefs extends Handler_Protected {
return $rv;
}
- private static function _plugin_needs_update($root_dir, $plugin_name) {
+ /**
+ * @return array{'stdout': false|string, 'stderr': false|string, 'git_status': int, 'need_update': bool}|null
+ */
+ private static function _plugin_needs_update(string $root_dir, string $plugin_name): ?array {
$plugin_dir = "$root_dir/plugins.local/" . basename($plugin_name);
$rv = null;
@@ -1086,7 +1108,10 @@ class Pref_Prefs extends Handler_Protected {
}
- private function _update_plugin($root_dir, $plugin_name) {
+ /**
+ * @return array{'stdout': false|string, 'stderr': false|string, 'git_status': int}
+ */
+ private function _update_plugin(string $root_dir, string $plugin_name): array {
$plugin_dir = "$root_dir/plugins.local/" . basename($plugin_name);
$rv = [];
@@ -1112,7 +1137,7 @@ class Pref_Prefs extends Handler_Protected {
}
// https://gist.github.com/mindplay-dk/a4aad91f5a4f1283a5e2#gistcomment-2036828
- private function _recursive_rmdir(string $dir, bool $keep_root = false) {
+ private function _recursive_rmdir(string $dir, bool $keep_root = false): bool {
// Handle bad arguments.
if (empty($dir) || !file_exists($dir)) {
return true; // No such file/dir$dir exists.
@@ -1137,7 +1162,7 @@ class Pref_Prefs extends Handler_Protected {
}
// https://stackoverflow.com/questions/7153000/get-class-name-from-file
- private function _get_class_name_from_file($file) {
+ private function _get_class_name_from_file(string $file): string {
$tokens = token_get_all(file_get_contents($file));
for ($i = 0; $i < count($tokens); $i++) {
@@ -1149,9 +1174,11 @@ class Pref_Prefs extends Handler_Protected {
}
}
}
+
+ return "";
}
- function uninstallPlugin() {
+ function uninstallPlugin(): void {
if ($_SESSION["access_level"] >= UserHelper::ACCESS_LEVEL_ADMIN) {
$plugin_name = basename(clean($_REQUEST['plugin']));
$status = 0;
@@ -1166,7 +1193,7 @@ class Pref_Prefs extends Handler_Protected {
}
}
- function installPlugin() {
+ function installPlugin(): void {
if ($_SESSION["access_level"] >= UserHelper::ACCESS_LEVEL_ADMIN && Config::get(Config::ENABLE_PLUGIN_INSTALLER)) {
$plugin_name = basename(clean($_REQUEST['plugin']));
$all_plugins = $this->_get_available_plugins();
@@ -1251,47 +1278,59 @@ class Pref_Prefs extends Handler_Protected {
}
}
- private function _get_available_plugins() {
+ /**
+ * @return array<int, array{'name': string, 'description': string, 'topics': array<int, string>, 'html_url': string, 'clone_url': string, 'last_update': string}>
+ */
+ private function _get_available_plugins(): array {
if ($_SESSION["access_level"] >= UserHelper::ACCESS_LEVEL_ADMIN && Config::get(Config::ENABLE_PLUGIN_INSTALLER)) {
- return json_decode(UrlHelper::fetch(['url' => 'https://tt-rss.org/plugins.json']), true);
+ $content = json_decode(UrlHelper::fetch(['url' => 'https://tt-rss.org/plugins.json']), true);
+
+ if ($content) {
+ return $content;
+ }
}
+
+ return [];
}
- function getAvailablePlugins() {
+
+ function getAvailablePlugins(): void {
if ($_SESSION["access_level"] >= UserHelper::ACCESS_LEVEL_ADMIN) {
print json_encode($this->_get_available_plugins());
+ } else {
+ print "[]";
}
}
- function checkForPluginUpdates() {
+ function checkForPluginUpdates(): void {
if ($_SESSION["access_level"] >= UserHelper::ACCESS_LEVEL_ADMIN && Config::get(Config::CHECK_FOR_UPDATES) && Config::get(Config::CHECK_FOR_PLUGIN_UPDATES)) {
$plugin_name = $_REQUEST["name"] ?? "";
-
$root_dir = dirname(dirname(__DIR__)); # we're in classes/pref/
- if (!empty($plugin_name)) {
- $rv = [["plugin" => $plugin_name, "rv" => self::_plugin_needs_update($root_dir, $plugin_name)]];
- } else {
- $rv = self::_get_updated_plugins();
- }
+ $rv = empty($plugin_name) ? self::_get_updated_plugins() : [
+ ["plugin" => $plugin_name, "rv" => self::_plugin_needs_update($root_dir, $plugin_name)],
+ ];
print json_encode($rv);
}
}
- function updateLocalPlugins() {
+ function updateLocalPlugins(): void {
if ($_SESSION["access_level"] >= UserHelper::ACCESS_LEVEL_ADMIN) {
$plugins = explode(",", $_REQUEST["plugins"] ?? "");
+ if ($plugins !== false) {
+ $plugins = array_filter($plugins, 'strlen');
+ }
+
# we're in classes/pref/
$root_dir = dirname(dirname(__DIR__));
$rv = [];
- if (count($plugins) > 0) {
+ if ($plugins) {
foreach ($plugins as $plugin_name) {
array_push($rv, ["plugin" => $plugin_name, "rv" => $this->_update_plugin($root_dir, $plugin_name)]);
}
- // @phpstan-ignore-next-line
} else {
$plugin_dirs = array_filter(glob("$root_dir/plugins.local/*"), "is_dir");
@@ -1301,7 +1340,7 @@ class Pref_Prefs extends Handler_Protected {
$test = self::_plugin_needs_update($root_dir, $plugin_name);
- if (!empty($test["o"]))
+ if (!empty($test["stdout"]))
array_push($rv, ["plugin" => $plugin_name, "rv" => $this->_update_plugin($root_dir, $plugin_name)]);
}
}
@@ -1311,20 +1350,20 @@ class Pref_Prefs extends Handler_Protected {
}
}
- function clearplugindata() {
+ function clearplugindata(): void {
$name = clean($_REQUEST["name"]);
PluginHost::getInstance()->clear_data(PluginHost::getInstance()->get_plugin($name));
}
- function customizeCSS() {
+ function customizeCSS(): void {
$value = get_pref(Prefs::USER_STYLESHEET);
$value = str_replace("<br/>", "\n", $value);
print json_encode(["value" => $value]);
}
- function activateprofile() {
+ function activateprofile(): void {
$id = (int) ($_REQUEST['id'] ?? 0);
$profile = ORM::for_table('ttrss_settings_profiles')
@@ -1338,7 +1377,7 @@ class Pref_Prefs extends Handler_Protected {
}
}
- function cloneprofile() {
+ function cloneprofile(): void {
$old_profile = $_REQUEST["old_profile"] ?? 0;
$new_title = clean($_REQUEST["new_title"]);
@@ -1367,7 +1406,7 @@ class Pref_Prefs extends Handler_Protected {
}
}
- function remprofiles() {
+ function remprofiles(): void {
$ids = $_REQUEST["ids"] ?? [];
ORM::for_table('ttrss_settings_profiles')
@@ -1377,7 +1416,7 @@ class Pref_Prefs extends Handler_Protected {
->delete_many();
}
- function addprofile() {
+ function addprofile(): void {
$title = clean($_REQUEST["title"]);
if ($title) {
@@ -1396,7 +1435,7 @@ class Pref_Prefs extends Handler_Protected {
}
}
- function saveprofile() {
+ function saveprofile(): void {
$id = (int)$_REQUEST["id"];
$title = clean($_REQUEST["value"]);
@@ -1413,7 +1452,7 @@ class Pref_Prefs extends Handler_Protected {
}
// TODO: this maybe needs to be unified with Public::getProfiles()
- function getProfiles() {
+ function getProfiles(): void {
$rv = [];
$profiles = ORM::for_table('ttrss_settings_profiles')
@@ -1442,21 +1481,21 @@ class Pref_Prefs extends Handler_Protected {
print json_encode($rv);
}
- private function _get_short_desc($pref_name) {
+ private function _get_short_desc(string $pref_name): string {
if (isset($this->pref_help[$pref_name][0])) {
return $this->pref_help[$pref_name][0];
}
return "";
}
- private function _get_help_text($pref_name) {
+ private function _get_help_text(string $pref_name): string {
if (isset($this->pref_help[$pref_name][1])) {
return $this->pref_help[$pref_name][1];
}
return "";
}
- private function appPasswordList() {
+ private function appPasswordList(): void {
?>
<div dojoType='fox.Toolbar'>
<div dojoType='fox.form.DropDownButton'>
@@ -1506,7 +1545,7 @@ class Pref_Prefs extends Handler_Protected {
<?php
}
- function deleteAppPasswords() {
+ function deleteAppPasswords(): void {
$passwords = ORM::for_table('ttrss_app_passwords')
->where('owner_uid', $_SESSION['uid'])
->where_in('id', $_REQUEST['ids'] ?? [])
@@ -1515,7 +1554,7 @@ class Pref_Prefs extends Handler_Protected {
$this->appPasswordList();
}
- function generateAppPassword() {
+ function generateAppPassword(): void {
$title = clean($_REQUEST['title']);
$new_password = make_password(16);
$new_salt = UserHelper::get_salt();
@@ -1536,11 +1575,11 @@ class Pref_Prefs extends Handler_Protected {
$this->appPasswordList();
}
- function previewDigest() {
+ function previewDigest(): void {
print json_encode(Digest::prepare_headlines_digest($_SESSION["uid"], 1, 16));
}
- static function _get_ssl_certificate_id() {
+ static function _get_ssl_certificate_id(): string {
if ($_SERVER["REDIRECT_SSL_CLIENT_M_SERIAL"] ?? false) {
return sha1($_SERVER["REDIRECT_SSL_CLIENT_M_SERIAL"] .
$_SERVER["REDIRECT_SSL_CLIENT_V_START"] .
@@ -1556,7 +1595,7 @@ class Pref_Prefs extends Handler_Protected {
return "";
}
- private function format_otp_secret($secret) {
+ private function format_otp_secret(string $secret): string {
return implode(" ", str_split($secret, 4));
}
}
diff --git a/classes/pref/system.php b/classes/pref/system.php
index 8bebcc7ce..10f196b55 100644
--- a/classes/pref/system.php
+++ b/classes/pref/system.php
@@ -2,19 +2,19 @@
class Pref_System extends Handler_Administrative {
- private $log_page_limit = 15;
+ private const LOG_PAGE_LIMIT = 15;
- function csrf_ignore($method) {
+ function csrf_ignore(string $method): bool {
$csrf_ignored = array("index");
return array_search($method, $csrf_ignored) !== false;
}
- function clearLog() {
+ function clearLog(): void {
$this->pdo->query("DELETE FROM ttrss_error_log");
}
- function sendTestEmail() {
+ function sendTestEmail(): void {
$mail_address = clean($_REQUEST["mail_address"]);
$mailer = new Mailer();
@@ -28,7 +28,7 @@ class Pref_System extends Handler_Administrative {
print json_encode(['rc' => $rc, 'error' => $mailer->error()]);
}
- function getphpinfo() {
+ function getphpinfo(): void {
ob_start();
phpinfo();
$info = ob_get_contents();
@@ -37,7 +37,7 @@ class Pref_System extends Handler_Administrative {
print preg_replace( '%^.*<body>(.*)</body>.*$%ms','$1', (string)$info);
}
- private function _log_viewer(int $page, int $severity) {
+ private function _log_viewer(int $page, int $severity): void {
$errno_values = [];
switch ($severity) {
@@ -56,8 +56,7 @@ class Pref_System extends Handler_Administrative {
$errno_filter_qpart = "true";
}
- $limit = $this->log_page_limit;
- $offset = $limit * $page;
+ $offset = self::LOG_PAGE_LIMIT * $page;
$sth = $this->pdo->prepare("SELECT
COUNT(id) AS total_pages
@@ -69,7 +68,7 @@ class Pref_System extends Handler_Administrative {
$sth->execute($errno_values);
if ($res = $sth->fetch()) {
- $total_pages = (int)($res["total_pages"] / $limit);
+ $total_pages = (int)($res["total_pages"] / self::LOG_PAGE_LIMIT);
} else {
$total_pages = 0;
}
@@ -134,7 +133,7 @@ class Pref_System extends Handler_Administrative {
$errno_filter_qpart
ORDER BY
ttrss_error_log.id DESC
- LIMIT $limit OFFSET $offset");
+ LIMIT ". self::LOG_PAGE_LIMIT ." OFFSET $offset");
$sth->execute($errno_values);
@@ -159,7 +158,7 @@ class Pref_System extends Handler_Administrative {
<?php
}
- function index() {
+ function index(): void {
$severity = (int) ($_REQUEST["severity"] ?? E_USER_WARNING);
$page = (int) ($_REQUEST["page"] ?? 0);
diff --git a/classes/pref/users.php b/classes/pref/users.php
index aeba296b2..c48619614 100644
--- a/classes/pref/users.php
+++ b/classes/pref/users.php
@@ -1,10 +1,10 @@
<?php
class Pref_Users extends Handler_Administrative {
- function csrf_ignore($method) {
+ function csrf_ignore(string $method): bool {
return $method == "index";
}
- function edit() {
+ function edit(): void {
$user = ORM::for_table('ttrss_users')
->select_expr("id,login,access_level,email,full_name,otp_enabled")
->find_one((int)$_REQUEST["id"])
@@ -20,7 +20,7 @@ class Pref_Users extends Handler_Administrative {
}
}
- function userdetails() {
+ function userdetails(): void {
$id = (int) clean($_REQUEST["id"]);
$sth = $this->pdo->prepare("SELECT login,
@@ -103,7 +103,7 @@ class Pref_Users extends Handler_Administrative {
}
- function editSave() {
+ function editSave(): void {
$id = (int)$_REQUEST['id'];
$password = clean($_REQUEST["password"]);
$user = ORM::for_table('ttrss_users')->find_one($id);
@@ -132,7 +132,7 @@ class Pref_Users extends Handler_Administrative {
}
}
- function remove() {
+ function remove(): void {
$ids = explode(",", clean($_REQUEST["ids"]));
foreach ($ids as $id) {
@@ -149,7 +149,7 @@ class Pref_Users extends Handler_Administrative {
}
}
- function add() {
+ function add(): void {
$login = clean($_REQUEST["login"]);
if (!$login) return; // no blank usernames
@@ -178,11 +178,11 @@ class Pref_Users extends Handler_Administrative {
}
}
- function resetPass() {
+ function resetPass(): void {
UserHelper::reset_password(clean($_REQUEST["id"]));
}
- function index() {
+ function index(): void {
global $access_level_names;