Преглед изворни кода

PHPStan level 6 for more files (#5264)

7 more files passing (see phpstan-next.txt)
Alexandre Alapetite пре 3 година
родитељ
комит
2118448133

+ 1 - 1
app/Controllers/authController.php

@@ -162,7 +162,7 @@ class FreshRSS_auth_Controller extends FreshRSS_ActionController {
 
 				// All is good, go back to the original request or the index.
 				$url = Minz_Url::unserialize(Minz_Request::param('original_request'));
-				if ($url === null) {
+				if (empty($url)) {
 					$url = [ 'c' => 'index', 'a' => 'index' ];
 				}
 				Minz_Request::good(_t('feedback.auth.login.success'), $url);

+ 8 - 7
app/Controllers/updateController.php

@@ -4,14 +4,14 @@ class FreshRSS_update_Controller extends FreshRSS_ActionController {
 
 	const LASTUPDATEFILE = 'last_update.txt';
 
-	public static function isGit() {
+	public static function isGit(): bool {
 		return is_dir(FRESHRSS_PATH . '/.git/');
 	}
 
 	/**
 	 * Automatic change to the new name of edge branch since FreshRSS 1.18.0.
 	 */
-	public static function migrateToGitEdge() {
+	public static function migrateToGitEdge(): bool {
 		$errorMessage = 'Error during git checkout to edge branch. Please change branch manually!';
 
 		if (!is_writable(FRESHRSS_PATH . '/.git/config')) {
@@ -44,7 +44,7 @@ class FreshRSS_update_Controller extends FreshRSS_ActionController {
 		return true;
 	}
 
-	public static function hasGitUpdate() {
+	public static function hasGitUpdate(): bool {
 		$cwd = getcwd();
 		chdir(FRESHRSS_PATH);
 		$output = array();
@@ -66,6 +66,7 @@ class FreshRSS_update_Controller extends FreshRSS_ActionController {
 			strpos($line, '[behind') !== false || strpos($line, '[ahead') !== false || strpos($line, '[gone') !== false;
 	}
 
+	/** @return string|true */
 	public static function gitPull() {
 		$cwd = getcwd();
 		chdir(FRESHRSS_PATH);
@@ -109,7 +110,7 @@ class FreshRSS_update_Controller extends FreshRSS_ActionController {
 		}
 	}
 
-	public function indexAction() {
+	public function indexAction(): void {
 		FreshRSS_View::prependTitle(_t('admin.update.title') . ' · ');
 
 		if (file_exists(UPDATE_FILENAME)) {
@@ -135,7 +136,7 @@ class FreshRSS_update_Controller extends FreshRSS_ActionController {
 		}
 	}
 
-	public function checkAction() {
+	public function checkAction(): void {
 		$this->view->_path('update/index.phtml');
 
 		if (file_exists(UPDATE_FILENAME)) {
@@ -216,7 +217,7 @@ class FreshRSS_update_Controller extends FreshRSS_ActionController {
 		}
 	}
 
-	public function applyAction() {
+	public function applyAction(): void {
 		if (FreshRSS_Context::$system_conf->disable_update || !file_exists(UPDATE_FILENAME) || !touch(FRESHRSS_PATH . '/index.html')) {
 			Minz_Request::forward(array('c' => 'update'), true);
 		}
@@ -278,7 +279,7 @@ class FreshRSS_update_Controller extends FreshRSS_ActionController {
 	/**
 	 * This action displays information about installation.
 	 */
-	public function checkInstallAction() {
+	public function checkInstallAction(): void {
 		FreshRSS_View::prependTitle(_t('admin.check_install.title') . ' · ');
 
 		$this->view->status_php = check_install_php();

+ 12 - 10
app/Models/Auth.php

@@ -9,12 +9,13 @@ class FreshRSS_Auth {
 	 */
 	const DEFAULT_COOKIE_DURATION = 7776000;
 
+	/** @var bool */
 	private static $login_ok = false;
 
 	/**
 	 * This method initializes authentication system.
 	 */
-	public static function init() {
+	public static function init(): bool {
 		if (isset($_SESSION['REMOTE_USER']) && $_SESSION['REMOTE_USER'] !== httpAuthUser()) {
 			//HTTP REMOTE_USER has changed
 			self::removeAccess();
@@ -47,9 +48,9 @@ class FreshRSS_Auth {
 	 * Required session parameters are also set in this method (such as
 	 * currentUser).
 	 *
-	 * @return boolean true if user can be connected, false else.
+	 * @return bool true if user can be connected, false otherwise.
 	 */
-	private static function accessControl() {
+	private static function accessControl(): bool {
 		$auth_type = FreshRSS_Context::$system_conf->auth_type;
 		switch ($auth_type) {
 		case 'form':
@@ -100,7 +101,7 @@ class FreshRSS_Auth {
 	/**
 	 * Gives access to the current user.
 	 */
-	public static function giveAccess() {
+	public static function giveAccess(): bool {
 		FreshRSS_Context::initUser();
 		if (FreshRSS_Context::$user_conf == null) {
 			self::$login_ok = false;
@@ -136,7 +137,7 @@ class FreshRSS_Auth {
 	 * @param string $scope general (default) or admin
 	 * @return boolean true if user has corresponding access, false else.
 	 */
-	public static function hasAccess($scope = 'general') {
+	public static function hasAccess($scope = 'general'): bool {
 		if (FreshRSS_Context::$user_conf == null) {
 			return false;
 		}
@@ -159,7 +160,7 @@ class FreshRSS_Auth {
 	/**
 	 * Removes all accesses for the current user.
 	 */
-	public static function removeAccess() {
+	public static function removeAccess(): void {
 		self::$login_ok = false;
 		Minz_Session::_params([
 			'loginOk' => false,
@@ -200,18 +201,18 @@ class FreshRSS_Auth {
 	/**
 	 * Return if authentication is enabled on this instance of FRSS.
 	 */
-	public static function accessNeedsLogin() {
+	public static function accessNeedsLogin(): bool {
 		return FreshRSS_Context::$system_conf->auth_type !== 'none';
 	}
 
 	/**
 	 * Return if authentication requires a PHP action.
 	 */
-	public static function accessNeedsAction() {
+	public static function accessNeedsAction(): bool {
 		return FreshRSS_Context::$system_conf->auth_type === 'form';
 	}
 
-	public static function csrfToken() {
+	public static function csrfToken(): string {
 		$csrf = Minz_Session::param('csrf');
 		if ($csrf == '') {
 			$salt = FreshRSS_Context::$system_conf->salt;
@@ -220,7 +221,8 @@ class FreshRSS_Auth {
 		}
 		return $csrf;
 	}
-	public static function isCsrfOk($token = null) {
+
+	public static function isCsrfOk(?string $token = null): bool {
 		$csrf = Minz_Session::param('csrf');
 		if ($token === null) {
 			$token = $_POST['_csrf'] ?? '';

+ 6 - 3
app/Models/FormAuth.php

@@ -13,7 +13,8 @@ class FreshRSS_FormAuth {
 		return password_verify($nonce . $hash, $challenge);
 	}
 
-	public static function getCredentialsFromCookie() {
+	/** @return array<string> */
+	public static function getCredentialsFromCookie(): array {
 		$token = Minz_Session::getLongTermCookie('FreshRSS_login');
 		if (!ctype_alnum($token)) {
 			return array();
@@ -36,6 +37,7 @@ class FreshRSS_FormAuth {
 		return [];
 	}
 
+	/** @return string|false */
 	private static function renewCookie(string $token) {
 		$token_file = DATA_PATH . '/tokens/' . $token . '.txt';
 		if (touch($token_file)) {
@@ -48,6 +50,7 @@ class FreshRSS_FormAuth {
 		return false;
 	}
 
+	/** @return string|false */
 	public static function makeCookie(string $username, string $password_hash) {
 		do {
 			$token = sha1(FreshRSS_Context::$system_conf->salt . $username . uniqid('' . mt_rand(), true));
@@ -61,7 +64,7 @@ class FreshRSS_FormAuth {
 		return self::renewCookie($token);
 	}
 
-	public static function deleteCookie() {
+	public static function deleteCookie(): void {
 		$token = Minz_Session::getLongTermCookie('FreshRSS_login');
 		if (ctype_alnum($token)) {
 			Minz_Session::deleteLongTermCookie('FreshRSS_login');
@@ -73,7 +76,7 @@ class FreshRSS_FormAuth {
 		}
 	}
 
-	public static function purgeTokens() {
+	public static function purgeTokens(): void {
 		$limits = FreshRSS_Context::$system_conf->limits;
 		$cookie_duration = empty($limits['cookie_duration']) ? FreshRSS_Auth::DEFAULT_COOKIE_DURATION : $limits['cookie_duration'];
 		$oldest = time() - $cookie_duration;

+ 10 - 6
lib/Minz/ActionController.php

@@ -17,9 +17,13 @@ class Minz_ActionController {
 	/** @var array<string,string> */
 	private $csp_policies;
 
+	/** @var Minz_View */
 	protected $view;
 
-	// Gives the possibility to override the default View type.
+	/**
+	 * Gives the possibility to override the default View type.
+	 * @var class-string
+	 */
 	public static $viewType = 'Minz_View';
 
 	public function __construct () {
@@ -37,7 +41,7 @@ class Minz_ActionController {
 	/**
 	 * Getteur
 	 */
-	public function view () {
+	public function view(): Minz_View {
 		return $this->view;
 	}
 
@@ -45,7 +49,7 @@ class Minz_ActionController {
 	 * Set default CSP policies.
 	 * @param array<string,string> $policies An array where keys are directives and values are sources.
 	 */
-	public static function _defaultCsp($policies) {
+	public static function _defaultCsp(array $policies): void {
 		if (!isset($policies['default-src'])) {
 			Minz_Log::warning('Default CSP policy is not declared', ADMIN_LOG);
 		}
@@ -61,9 +65,9 @@ class Minz_ActionController {
 	 * - https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
 	 * - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/default-src
 	 *
-	 * @param array $policies An array where keys are directives and values are sources.
+	 * @param array<string,string> $policies An array where keys are directives and values are sources.
 	 */
-	protected function _csp($policies) {
+	protected function _csp(array $policies): void {
 		if (!isset($policies['default-src'])) {
 			$action = Minz_Request::controllerName() . '#' . Minz_Request::actionName();
 			Minz_Log::warning(
@@ -77,7 +81,7 @@ class Minz_ActionController {
 	/**
 	 * Send HTTP Content-Security-Policy header based on declared policies.
 	 */
-	public function declareCspHeader() {
+	public function declareCspHeader(): void {
 		$policies = [];
 		foreach ($this->csp_policies as $directive => $sources) {
 			$policies[] = $directive . ' ' . $sources;

+ 6 - 3
lib/Minz/FrontController.php

@@ -24,6 +24,8 @@
  * It is generally invoqued by an index.php file at the root.
  */
 class Minz_FrontController {
+
+	/** @var Minz_Dispatcher */
 	protected $dispatcher;
 
 	/**
@@ -53,7 +55,7 @@ class Minz_FrontController {
 	/**
 	 * Démarre l'application (lance le dispatcher et renvoie la réponse)
 	 */
-	public function run() {
+	public function run(): void {
 		try {
 			$this->dispatcher->run();
 		} catch (Minz_Exception $e) {
@@ -80,8 +82,9 @@ class Minz_FrontController {
 
 	/**
 	 * Kills the programme
+	 * @return never
 	 */
-	public static function killApp($txt = '') {
+	public static function killApp(string $txt = '') {
 		header('HTTP 1.1 500 Internal Server Error', true, 500);
 		if (function_exists('errorMessageInfo')) {
 			//If the application has defined a custom error message function
@@ -90,7 +93,7 @@ class Minz_FrontController {
 		die('### Application problem ###<br />' . "\n" . $txt);
 	}
 
-	private function setReporting() {
+	private function setReporting(): void {
 		$envType = getenv('FRESHRSS_ENV');
 		if ($envType == '') {
 			$conf = Minz_Configuration::get('system');

+ 9 - 4
lib/Minz/ModelArray.php

@@ -10,6 +10,7 @@
 class Minz_ModelArray {
 	/**
 	 * $filename est le nom du fichier
+	 * @var string
 	 */
 	protected $filename;
 
@@ -22,7 +23,8 @@ class Minz_ModelArray {
 		$this->filename = $filename;
 	}
 
-	protected function loadArray() {
+	/** @return array<string,mixed> */
+	protected function loadArray(): array {
 		if (!file_exists($this->filename)) {
 			throw new Minz_FileNotExistException($this->filename, Minz_Exception::WARNING);
 		} elseif (($handle = $this->getLock()) === false) {
@@ -42,8 +44,9 @@ class Minz_ModelArray {
 
 	/**
 	 * Sauve le tableau $array dans le fichier $filename
-	 **/
-	protected function writeArray($array) {
+	 * @param array<string,mixed> $array
+	 */
+	protected function writeArray(array $array): bool {
 		if (file_put_contents($this->filename, "<?php\n return " . var_export($array, true) . ';', LOCK_EX) === false) {
 			throw new Minz_PermissionDeniedException($this->filename);
 		}
@@ -53,6 +56,7 @@ class Minz_ModelArray {
 		return true;
 	}
 
+	/** @return resource|false */
 	private function getLock() {
 		$handle = fopen($this->filename, 'r');
 		if ($handle === false) {
@@ -73,7 +77,8 @@ class Minz_ModelArray {
 		}
 	}
 
-	private function releaseLock($handle) {
+	/** @param resource $handle */
+	private function releaseLock($handle): void {
 		flock($handle, LOCK_UN);
 		fclose($handle);
 	}

+ 11 - 9
lib/Minz/Url.php

@@ -15,7 +15,7 @@ class Minz_Url {
 	 * @param bool|string $absolute
 	 * @return string Formatted URL
 	 */
-	public static function display ($url = array (), $encoding = 'html', $absolute = false) {
+	public static function display($url = [], string $encoding = 'html', $absolute = false): string {
 		$isArray = is_array($url);
 
 		if ($isArray) {
@@ -60,7 +60,7 @@ class Minz_Url {
 	 * @param string $encodage pour indiquer comment encoder les & (& ou &amp; pour html)
 	 * @return string uri sous la forme ?key=value&key2=value2
 	 */
-	private static function printUri($url, $encodage) {
+	private static function printUri($url, string $encodage): string {
 		$uri = '';
 		$separator = '?';
 		$anchor = '';
@@ -129,7 +129,8 @@ class Minz_Url {
 		return $url_checked;
 	}
 
-	public static function serialize($url = []) {
+	/** @param array<string,string|array<string,string>> $url */
+	public static function serialize(array $url = []): string {
 		try {
 			return base64_encode(json_encode($url, JSON_THROW_ON_ERROR));
 		} catch (\Throwable $exception) {
@@ -137,19 +138,20 @@ class Minz_Url {
 		}
 	}
 
-	public static function unserialize($url = '') {
+	/** @return array<string,string|array<string,string>> */
+	public static function unserialize(string $url = ''): array {
 		try {
-			return json_decode(base64_decode($url), true, JSON_THROW_ON_ERROR);
+			return json_decode(base64_decode($url), true, JSON_THROW_ON_ERROR) ?? [];
 		} catch (\Throwable $exception) {
-			return '';
+			return [];
 		}
 	}
 
 	/**
 	 * Returns an array representing the URL as passed in the address bar
-	 * @return array URL representation
+	 * @return array<string,string|array<string,string>> URL representation
 	 */
-	public static function build () {
+	public static function build(): array {
 		$url = [
 			'c' => $_GET['c'] ?? Minz_Request::defaultControllerName(),
 			'a' => $_GET['a'] ?? Minz_Request::defaultActionName(),
@@ -170,7 +172,7 @@ class Minz_Url {
  * @param string|int ...$args
  * @return string|false
  */
-function _url ($controller, $action, ...$args) {
+function _url(string $controller, string $action, ...$args) {
 	$nb_args = count($args);
 
 	if ($nb_args % 2 !== 0) {

+ 0 - 7
tests/phpstan-next.txt

@@ -5,10 +5,8 @@
 # find . -type d -name 'vendor' -prune -o -name '*.php' -exec sh -c 'vendor/bin/phpstan analyse --level 6 --memory-limit 512M {} >/dev/null 2>/dev/null || echo {}' \;
 
 ./app/Controllers/feedController.php
-./app/Controllers/updateController.php
 ./app/Controllers/userController.php
 ./app/install.php
-./app/Models/Auth.php
 ./app/Models/Category.php
 ./app/Models/CategoryDAO.php
 ./app/Models/ConfigurationSetter.php
@@ -16,7 +14,6 @@
 ./app/Models/Feed.php
 ./app/Models/FeedDAO.php
 ./app/Models/FilterAction.php
-./app/Models/FormAuth.php
 ./app/Models/Search.php
 ./app/Models/Share.php
 ./app/Models/TagDAO.php
@@ -28,16 +25,12 @@
 ./cli/i18n/I18nFile.php
 ./cli/i18n/I18nValue.php
 ./lib/http-conditional.php
-./lib/Minz/ActionController.php
 ./lib/Minz/Configuration.php
 ./lib/Minz/Dispatcher.php
-./lib/Minz/FrontController.php
 ./lib/Minz/Log.php
 ./lib/Minz/Migrator.php
-./lib/Minz/ModelArray.php
 ./lib/Minz/Paginator.php
 ./lib/Minz/Request.php
 ./lib/Minz/Session.php
 ./lib/Minz/Translate.php
-./lib/Minz/Url.php
 ./lib/Minz/View.php