Initial go at PHPStan rule level 6.

This commit is contained in:
wn_ 2021-11-10 21:38:25 +00:00
parent 87a30d88d3
commit 4cc3374f9f
12 changed files with 93 additions and 48 deletions

View File

@ -231,9 +231,13 @@ class Config {
Config::T_STRING ], Config::T_STRING ],
]; ];
/** @var Config|null */
private static $instance; private static $instance;
/** @var array<string, array<bool|int|string>> */
private $params = []; private $params = [];
/** @var array<string, mixed> */
private $version = []; private $version = [];
/** @var Db_Migrations|null $migrations */ /** @var Db_Migrations|null $migrations */
@ -268,10 +272,16 @@ class Config {
directory, its contents are displayed instead of git commit-based version, this could be generated directory, its contents are displayed instead of git commit-based version, this could be generated
based on source git tree commit used when creating the package */ based on source git tree commit used when creating the package */
/**
* @return array<string, mixed>|string
*/
static function get_version(bool $as_string = true) { static function get_version(bool $as_string = true) {
return self::get_instance()->_get_version($as_string); return self::get_instance()->_get_version($as_string);
} }
/**
* @return array<string, mixed>|string
*/
private function _get_version(bool $as_string = true) { private function _get_version(bool $as_string = true) {
$root_dir = dirname(__DIR__); $root_dir = dirname(__DIR__);
@ -298,7 +308,10 @@ class Config {
return $as_string ? $this->version["version"] : $this->version; return $as_string ? $this->version["version"] : $this->version;
} }
static function get_version_from_git(string $dir) { /**
* @return array<string, int|string>
*/
static function get_version_from_git(string $dir): array {
$descriptorspec = [ $descriptorspec = [
1 => ["pipe", "w"], // STDOUT 1 => ["pipe", "w"], // STDOUT
2 => ["pipe", "w"], // STDERR 2 => ["pipe", "w"], // STDERR
@ -364,6 +377,9 @@ class Config {
return self::get_migrations()->get_version(); return self::get_migrations()->get_version();
} }
/**
* @return bool|int|string
*/
static function cast_to(string $value, int $type_hint) { static function cast_to(string $value, int $type_hint) {
switch ($type_hint) { switch ($type_hint) {
case self::T_BOOL: case self::T_BOOL:
@ -375,24 +391,30 @@ class Config {
} }
} }
/**
* @return bool|int|string
*/
private function _get(string $param) { private function _get(string $param) {
list ($value, $type_hint) = $this->params[$param]; list ($value, $type_hint) = $this->params[$param];
return $this->cast_to($value, $type_hint); return $this->cast_to($value, $type_hint);
} }
private function _add(string $param, string $default, int $type_hint) { private function _add(string $param, string $default, int $type_hint): void {
$override = getenv(self::_ENVVAR_PREFIX . $param); $override = getenv(self::_ENVVAR_PREFIX . $param);
$this->params[$param] = [ self::cast_to($override !== false ? $override : $default, $type_hint), $type_hint ]; $this->params[$param] = [ self::cast_to($override !== false ? $override : $default, $type_hint), $type_hint ];
} }
static function add(string $param, string $default, int $type_hint = Config::T_STRING) { static function add(string $param, string $default, int $type_hint = Config::T_STRING): void {
$instance = self::get_instance(); $instance = self::get_instance();
return $instance->_add($param, $default, $type_hint); $instance->_add($param, $default, $type_hint);
} }
/**
* @return bool|int|string
*/
static function get(string $param) { static function get(string $param) {
$instance = self::get_instance(); $instance = self::get_instance();
@ -431,6 +453,9 @@ class Config {
/* sanity check stuff */ /* sanity check stuff */
/**
* @return array<int, array<string, string>> A list of entries identifying tt-rss tables with bad config
*/
private static function check_mysql_tables() { private static function check_mysql_tables() {
$pdo = Db::pdo(); $pdo = Db::pdo();
@ -447,7 +472,7 @@ class Config {
return $bad_tables; return $bad_tables;
} }
static function sanity_check() { static function sanity_check(): void {
/* /*
we don't actually need the DB object right now but some checks below might use ORM which won't be initialized we don't actually need the DB object right now but some checks below might use ORM which won't be initialized
@ -621,11 +646,11 @@ class Config {
} }
} }
private static function format_error($msg) { private static function format_error(string $msg): string {
return "<div class=\"alert alert-danger\">$msg</div>"; return "<div class=\"alert alert-danger\">$msg</div>";
} }
static function get_override_links() { static function get_override_links(): string {
$rv = ""; $rv = "";
$local_css = get_theme_path(self::get(self::LOCAL_OVERRIDE_STYLESHEET)); $local_css = get_theme_path(self::get(self::LOCAL_OVERRIDE_STYLESHEET));
@ -637,7 +662,7 @@ class Config {
return $rv; return $rv;
} }
static function get_user_agent() { static function get_user_agent(): string {
return sprintf(self::get(self::HTTP_USER_AGENT), self::get_version()); return sprintf(self::get(self::HTTP_USER_AGENT), self::get_version());
} }
} }

View File

@ -17,7 +17,7 @@ class Db
} }
} }
static function NOW() { static function NOW(): string {
return date("Y-m-d H:i:s", time()); return date("Y-m-d H:i:s", time());
} }
@ -25,7 +25,7 @@ class Db
// //
} }
public static function get_dsn() { public static function get_dsn(): string {
$db_port = Config::get(Config::DB_PORT) ? ';port=' . Config::get(Config::DB_PORT) : ''; $db_port = Config::get(Config::DB_PORT) ? ';port=' . Config::get(Config::DB_PORT) : '';
$db_host = Config::get(Config::DB_HOST) ? ';host=' . Config::get(Config::DB_HOST) : ''; $db_host = Config::get(Config::DB_HOST) ? ';host=' . Config::get(Config::DB_HOST) : '';
if (Config::get(Config::DB_TYPE) == "mysql" && Config::get(Config::MYSQL_CHARSET)) { if (Config::get(Config::DB_TYPE) == "mysql" && Config::get(Config::MYSQL_CHARSET)) {
@ -88,12 +88,11 @@ class Db
return self::$instance->pdo; return self::$instance->pdo;
} }
public static function sql_random_function() { public static function sql_random_function(): string {
if (Config::get(Config::DB_TYPE) == "mysql") { if (Config::get(Config::DB_TYPE) == "mysql") {
return "RAND()"; return "RAND()";
} else {
return "RANDOM()";
} }
return "RANDOM()";
} }
} }

View File

@ -7,7 +7,11 @@ class Errors {
const E_SCHEMA_MISMATCH = "E_SCHEMA_MISMATCH"; const E_SCHEMA_MISMATCH = "E_SCHEMA_MISMATCH";
const E_URL_SCHEME_MISMATCH = "E_URL_SCHEME_MISMATCH"; const E_URL_SCHEME_MISMATCH = "E_URL_SCHEME_MISMATCH";
static function to_json(string $code, array $params = []) { /**
* @param Errors::E_* $code
* @param array<string, string> $params
*/
static function to_json(string $code, array $params = []): string {
return json_encode(["error" => ["code" => $code, "params" => $params]]); return json_encode(["error" => ["code" => $code, "params" => $params]]);
} }
} }

View File

@ -1,6 +1,9 @@
<?php <?php
class Logger { class Logger {
/** @var Logger|null */
private static $instance; private static $instance;
/** @var Logger_Adapter|null */
private $adapter; private $adapter;
const LOG_DEST_SQL = "sql"; const LOG_DEST_SQL = "sql";
@ -25,11 +28,11 @@ class Logger {
16384 => 'E_USER_DEPRECATED', 16384 => 'E_USER_DEPRECATED',
32767 => 'E_ALL']; 32767 => 'E_ALL'];
static function log_error(int $errno, string $errstr, string $file, int $line, $context) { static function log_error(int $errno, string $errstr, string $file, int $line, string $context): bool {
return self::get_instance()->_log_error($errno, $errstr, $file, $line, $context); return self::get_instance()->_log_error($errno, $errstr, $file, $line, $context);
} }
private function _log_error($errno, $errstr, $file, $line, $context) { private function _log_error(int $errno, string $errstr, string $file, int $line, string $context): bool {
//if ($errno == E_NOTICE) return false; //if ($errno == E_NOTICE) return false;
if ($this->adapter) if ($this->adapter)
@ -38,11 +41,11 @@ class Logger {
return false; return false;
} }
static function log(int $errno, string $errstr, $context = "") { static function log(int $errno, string $errstr, string $context = ""): bool {
return self::get_instance()->_log($errno, $errstr, $context); return self::get_instance()->_log($errno, $errstr, $context);
} }
private function _log(int $errno, string $errstr, $context = "") { private function _log(int $errno, string $errstr, string $context = ""): bool {
if ($this->adapter) if ($this->adapter)
return $this->adapter->log_error($errno, $errstr, '', 0, $context); return $this->adapter->log_error($errno, $errstr, '', 0, $context);
else else
@ -65,7 +68,7 @@ class Logger {
$this->adapter = new Logger_Stdout(); $this->adapter = new Logger_Stdout();
break; break;
default: default:
$this->adapter = false; $this->adapter = null;
} }
if ($this->adapter && !implements_interface($this->adapter, "Logger_Adapter")) if ($this->adapter && !implements_interface($this->adapter, "Logger_Adapter"))

View File

@ -1,4 +1,4 @@
<?php <?php
interface Logger_Adapter { interface Logger_Adapter {
function log_error(int $errno, string $errstr, string $file, int $line, $context); function log_error(int $errno, string $errstr, string $file, int $line, string $context): bool;
} }

View File

@ -10,7 +10,7 @@ class Logger_SQL implements Logger_Adapter {
ORM::configure('return_result_sets', true, $conn); ORM::configure('return_result_sets', true, $conn);
} }
function log_error(int $errno, string $errstr, string $file, int $line, $context) { function log_error(int $errno, string $errstr, string $file, int $line, string $context): bool {
if (Config::get_schema_version() > 117) { if (Config::get_schema_version() > 117) {

View File

@ -1,7 +1,7 @@
<?php <?php
class Logger_Stdout implements Logger_Adapter { class Logger_Stdout implements Logger_Adapter {
function log_error(int $errno, string $errstr, string $file, int $line, $context) { function log_error(int $errno, string $errstr, string $file, int $line, string $context): bool {
switch ($errno) { switch ($errno) {
case E_ERROR: case E_ERROR:
@ -25,6 +25,7 @@ class Logger_Stdout implements Logger_Adapter {
print "[EEE] $priority $errname ($file:$line) $errstr\n"; print "[EEE] $priority $errname ($file:$line) $errstr\n";
return true;
} }
} }

View File

@ -1,7 +1,7 @@
<?php <?php
class Logger_Syslog implements Logger_Adapter { class Logger_Syslog implements Logger_Adapter {
function log_error(int $errno, string $errstr, string $file, int $line, $context) { function log_error(int $errno, string $errstr, string $file, int $line, string $context): bool {
switch ($errno) { switch ($errno) {
case E_ERROR: case E_ERROR:
@ -25,6 +25,7 @@ class Logger_Syslog implements Logger_Adapter {
syslog($priority, "[tt-rss] $errname ($file:$line) $errstr"); syslog($priority, "[tt-rss] $errname ($file:$line) $errstr");
return true;
} }
} }

View File

@ -6,16 +6,19 @@ class UrlHelper {
"tel" "tel"
]; ];
static $fetch_last_error; static string $fetch_last_error;
static $fetch_last_error_code; static int $fetch_last_error_code;
static $fetch_last_error_content; static string $fetch_last_error_content;
static $fetch_last_content_type; static string $fetch_last_content_type;
static $fetch_last_modified; static string $fetch_last_modified;
static $fetch_effective_url; static string $fetch_effective_url;
static $fetch_effective_ip_addr; static string $fetch_effective_ip_addr;
static $fetch_curl_used; static bool $fetch_curl_used;
static function build_url($parts) { /**
* @param array<string, string> $parts
*/
static function build_url(array $parts): string {
$tmp = $parts['scheme'] . "://" . $parts['host']; $tmp = $parts['scheme'] . "://" . $parts['host'];
if (isset($parts['path'])) $tmp .= $parts['path']; if (isset($parts['path'])) $tmp .= $parts['path'];
@ -81,7 +84,10 @@ class UrlHelper {
} }
// extended filtering involves validation for safe ports and loopback // extended filtering involves validation for safe ports and loopback
static function validate($url, $extended_filtering = false) { /**
* @return bool|string false if something went wrong, otherwise the URL string
*/
static function validate(string $url, bool $extended_filtering = false) {
$url = clean($url); $url = clean($url);
@ -138,7 +144,10 @@ class UrlHelper {
return $url; return $url;
} }
static function resolve_redirects($url, $timeout, $nest = 0) { /**
* @return bool|string
*/
static function resolve_redirects(string $url, int $timeout, int $nest = 0) {
// too many redirects // too many redirects
if ($nest > 10) if ($nest > 10)
@ -189,12 +198,15 @@ class UrlHelper {
return false; return false;
} }
/**
* @return bool|string false if something went wrong, otherwise string contents
*/
// TODO: max_size currently only works for CURL transfers // TODO: max_size currently only works for CURL transfers
// TODO: multiple-argument way is deprecated, first parameter is a hash now // TODO: multiple-argument way is deprecated, first parameter is a hash now
public static function fetch($options /* previously: 0: $url , 1: $type = false, 2: $login = false, 3: $pass = false, public static function fetch($options /* previously: 0: $url , 1: $type = false, 2: $login = false, 3: $pass = false,
4: $post_query = false, 5: $timeout = false, 6: $timestamp = 0, 7: $useragent = false*/) { 4: $post_query = false, 5: $timeout = false, 6: $timestamp = 0, 7: $useragent = false*/) {
self::$fetch_last_error = false; self::$fetch_last_error = "";
self::$fetch_last_error_code = -1; self::$fetch_last_error_code = -1;
self::$fetch_last_error_content = ""; self::$fetch_last_error_content = "";
self::$fetch_last_content_type = ""; self::$fetch_last_content_type = "";
@ -510,7 +522,7 @@ class UrlHelper {
} }
} }
public static function url_to_youtube_vid($url) { public static function url_to_youtube_vid(string $url) { # : bool|string
$url = str_replace("youtube.com", "youtube-nocookie.com", $url); $url = str_replace("youtube.com", "youtube-nocookie.com", $url);
$regexps = [ $regexps = [

View File

@ -1,5 +1,5 @@
parameters: parameters:
level: 5 level: 6
ignoreErrors: ignoreErrors:
- '#Constant.*\b(SUBSTRING_FOR_DATE|SCHEMA_VERSION|SELF_USER_AGENT|LABEL_BASE_INDEX|PLUGIN_FEED_BASE_INDEX)\b.*not found#' - '#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.#' - '#Comparison operation ">" between int<1, max> and 0 is always true.#'

View File

@ -12,7 +12,7 @@
Config::sanity_check(); Config::sanity_check();
function make_stampfile($filename) { function make_stampfile(string $filename): bool {
$fp = fopen(Config::get(Config::LOCK_DIRECTORY) . "/$filename", "w"); $fp = fopen(Config::get(Config::LOCK_DIRECTORY) . "/$filename", "w");
if (flock($fp, LOCK_EX | LOCK_NB)) { if (flock($fp, LOCK_EX | LOCK_NB)) {
@ -25,7 +25,7 @@
} }
} }
function cleanup_tags($days = 14, $limit = 1000) { function cleanup_tags(int $days = 14, int $limit = 1000): int {
$days = (int) $days; $days = (int) $days;

View File

@ -37,7 +37,7 @@
/** /**
* @SuppressWarnings(unused) * @SuppressWarnings(unused)
*/ */
function reap_children() { function reap_children(): int {
global $children; global $children;
global $ctimes; global $ctimes;
@ -64,7 +64,7 @@
return count($tmp); return count($tmp);
} }
function check_ctimes() { function check_ctimes(): void {
global $ctimes; global $ctimes;
foreach (array_keys($ctimes) as $pid) { foreach (array_keys($ctimes) as $pid) {
@ -80,7 +80,7 @@
/** /**
* @SuppressWarnings(unused) * @SuppressWarnings(unused)
*/ */
function sigchld_handler($signal) { function sigchld_handler(int $signo, mixed $siginfo): void {
$running_jobs = reap_children(); $running_jobs = reap_children();
Debug::log("Received SIGCHLD, $running_jobs active tasks left."); Debug::log("Received SIGCHLD, $running_jobs active tasks left.");
@ -88,7 +88,7 @@
pcntl_waitpid(-1, $status, WNOHANG); pcntl_waitpid(-1, $status, WNOHANG);
} }
function shutdown($caller_pid) { function shutdown(int $caller_pid): void {
if ($caller_pid == posix_getpid()) { if ($caller_pid == posix_getpid()) {
if (file_exists(Config::get(Config::LOCK_DIRECTORY) . "/update_daemon.lock")) { if (file_exists(Config::get(Config::LOCK_DIRECTORY) . "/update_daemon.lock")) {
Debug::log("Removing lockfile (master)..."); Debug::log("Removing lockfile (master)...");
@ -97,7 +97,7 @@
} }
} }
function task_shutdown() { function task_shutdown(): void {
$pid = posix_getpid(); $pid = posix_getpid();
if (file_exists(Config::get(Config::LOCK_DIRECTORY) . "/update_daemon-$pid.lock")) { if (file_exists(Config::get(Config::LOCK_DIRECTORY) . "/update_daemon-$pid.lock")) {
@ -106,13 +106,13 @@
} }
} }
function sigint_handler() { function sigint_handler(): void {
Debug::log("[MASTER] SIG_INT received, shutting down master process."); Debug::log("[MASTER] SIG_INT received, shutting down master process.");
shutdown(posix_getpid()); shutdown(posix_getpid());
die; die;
} }
function task_sigint_handler() { function task_sigint_handler(): void {
Debug::log("[TASK] SIG_INT received, shutting down task."); Debug::log("[TASK] SIG_INT received, shutting down task.");
task_shutdown(); task_shutdown();
die; die;