diff options
| author | 2022-01-04 13:59:09 +0100 | |
|---|---|---|
| committer | 2022-01-04 13:59:09 +0100 | |
| commit | 1335a0e3cf11a0d4248e9eaaf748b89e6df741ef (patch) | |
| tree | ed6a8d17cef0581e5b0402dc8dfedd42fabfe9c7 | |
| parent | 0988b0c2be911133f883313bc3a858670192cc69 (diff) | |
PHPStan level 5 (#4110)
* Fix most PHPDocs errors
Contributes to https://github.com/FreshRSS/FreshRSS/issues/4103
https://phpstan.org/writing-php-code/phpdoc-types
* Avoid func_get_args
Use variadic syntax instead https://php.net/manual/functions.arguments#functions.variable-arg-list
And avoid dynamic functions names when possible to more easily identify calls and unused functions.
Contributes to https://github.com/FreshRSS/FreshRSS/issues/4103
* PHPStan level 3
* PHPStand level 4
* Update default to PHPStan level 4
* Towards level 5
* Fix level 4 regression
* Towards level 5
* Pass PHPStan level 5
* Towards level 6
* Remove erronenous regression from changelog
https://github.com/FreshRSS/FreshRSS/pull/4116
73 files changed, 403 insertions, 170 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index afee5e855..e8042bf6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,6 @@ ## 2022-01-02 FreshRSS 1.19.1 * Bug fixing - * Fix regression when creating a new user (only with PostgreSQL, MariaDB/MySQL) [#4116](https://github.com/FreshRSS/FreshRSS/pull/4116) * Fix some filters for automatic article actions (e.g., `!pubdate:P3d`) [#4092](https://github.com/FreshRSS/FreshRSS/pull/4092) * Features * New search operator on article IDs (useful to show a single article, extensions) [#4058](https://github.com/FreshRSS/FreshRSS/pull/4058) diff --git a/app/Controllers/apiController.php b/app/Controllers/apiController.php index 14dac938c..7843a33f1 100644 --- a/app/Controllers/apiController.php +++ b/app/Controllers/apiController.php @@ -3,7 +3,7 @@ /** * This controller manage API-related features. */ -class FreshRSS_api_Controller extends Minz_ActionController { +class FreshRSS_api_Controller extends FreshRSS_ActionController { /** * Update the user API password. diff --git a/app/Controllers/authController.php b/app/Controllers/authController.php index 085278a4f..fedabea8e 100644 --- a/app/Controllers/authController.php +++ b/app/Controllers/authController.php @@ -3,7 +3,7 @@ /** * This controller handles action about authentication. */ -class FreshRSS_auth_Controller extends Minz_ActionController { +class FreshRSS_auth_Controller extends FreshRSS_ActionController { /** * This action handles authentication management page. * diff --git a/app/Controllers/categoryController.php b/app/Controllers/categoryController.php index 3ec88460a..7226e44af 100644 --- a/app/Controllers/categoryController.php +++ b/app/Controllers/categoryController.php @@ -4,7 +4,7 @@ * Controller to handle actions relative to categories. * User needs to be connected. */ -class FreshRSS_category_Controller extends Minz_ActionController { +class FreshRSS_category_Controller extends FreshRSS_ActionController { /** * This action is called before every other action in that class. It is * the common boiler plate for every action. It is triggered by the diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php index b8bf97e77..a263db99c 100755 --- a/app/Controllers/configureController.php +++ b/app/Controllers/configureController.php @@ -3,7 +3,7 @@ /** * Controller to handle every configuration options. */ -class FreshRSS_configure_Controller extends Minz_ActionController { +class FreshRSS_configure_Controller extends FreshRSS_ActionController { /** * This action is called before every other action in that class. It is * the common boiler plate for every action. It is triggered by the @@ -249,7 +249,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { $volatile = [ 'enable_keep_period' => true, 'keep_period_count' => $matches['count'], - 'keep_period_unit' => str_replace($matches['count'], 1, $keepPeriod), + 'keep_period_unit' => str_replace($matches['count'], '1', $keepPeriod), ]; } FreshRSS_Context::$user_conf->volatile = $volatile; @@ -295,7 +295,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { if ($query['search']) { $query['search'] = urldecode($query['search']); } - $queries[] = new FreshRSS_UserQuery($query, $feed_dao, $category_dao, $tag_dao); + $queries[intval($key)] = new FreshRSS_UserQuery($query, $feed_dao, $category_dao, $tag_dao); } FreshRSS_Context::$user_conf->queries = $queries; FreshRSS_Context::$user_conf->save(); @@ -304,7 +304,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { } else { $this->view->queries = array(); foreach (FreshRSS_Context::$user_conf->queries as $key => $query) { - $this->view->queries[$key] = new FreshRSS_UserQuery($query, $feed_dao, $category_dao, $tag_dao); + $this->view->queries[intval($key)] = new FreshRSS_UserQuery($query, $feed_dao, $category_dao, $tag_dao); } } @@ -315,6 +315,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { $id = Minz_Request::param('id'); $this->view->displaySlider = false; if (false !== $id) { + $id = intval($id); $this->view->displaySlider = true; $this->view->query = $this->view->queries[$id]; $this->view->queryId = $id; diff --git a/app/Controllers/entryController.php b/app/Controllers/entryController.php index 2f5c6594c..5afd24a91 100755 --- a/app/Controllers/entryController.php +++ b/app/Controllers/entryController.php @@ -3,7 +3,7 @@ /** * Controller to handle every entry actions. */ -class FreshRSS_entry_Controller extends Minz_ActionController { +class FreshRSS_entry_Controller extends FreshRSS_ActionController { /** * JavaScript request or not. diff --git a/app/Controllers/errorController.php b/app/Controllers/errorController.php index 658cc71af..999236031 100644 --- a/app/Controllers/errorController.php +++ b/app/Controllers/errorController.php @@ -3,7 +3,7 @@ /** * Controller to handle error page. */ -class FreshRSS_error_Controller extends Minz_ActionController { +class FreshRSS_error_Controller extends FreshRSS_ActionController { /** * This action is the default one for the controller. * diff --git a/app/Controllers/extensionController.php b/app/Controllers/extensionController.php index 69f52cebf..3a3affb99 100644 --- a/app/Controllers/extensionController.php +++ b/app/Controllers/extensionController.php @@ -3,7 +3,7 @@ /** * The controller to manage extensions. */ -class FreshRSS_extension_Controller extends Minz_ActionController { +class FreshRSS_extension_Controller extends FreshRSS_ActionController { /** * This action is called before every other action in that class. It is * the common boiler plate for every action. It is triggered by the diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index e95bd8763..de243501b 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -3,7 +3,7 @@ /** * Controller to handle every feed actions. */ -class FreshRSS_feed_Controller extends Minz_ActionController { +class FreshRSS_feed_Controller extends FreshRSS_ActionController { /** * This action is called before every other action in that class. It is * the common boiler plate for every action. It is triggered by the @@ -46,10 +46,10 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $url = trim($url); - /** @var string $url */ + /** @var string|null $url */ $url = Minz_ExtensionManager::callHook('check_url_before_add', $url); if (null === $url) { - throw new FreshRSS_FeedNotAdded_Exception($url, $title); + throw new FreshRSS_FeedNotAdded_Exception($url); } $cat = null; @@ -77,10 +77,10 @@ class FreshRSS_feed_Controller extends Minz_ActionController { throw new FreshRSS_AlreadySubscribed_Exception($url, $feed->name()); } - /** @var FreshRSS_Feed $feed */ + /** @var FreshRSS_Feed|null $feed */ $feed = Minz_ExtensionManager::callHook('feed_before_insert', $feed); if ($feed === null) { - throw new FreshRSS_FeedNotAdded_Exception($url, $feed->name()); + throw new FreshRSS_FeedNotAdded_Exception($url); } $values = array( @@ -97,7 +97,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $id = $feedDAO->addFeed($values); if (!$id) { // There was an error in database... we cannot say what here. - throw new FreshRSS_FeedNotAdded_Exception($url, $feed->name()); + throw new FreshRSS_FeedNotAdded_Exception($url); } $feed->_id($id); @@ -186,7 +186,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $attributes['timeout'] = $timeout > 0 ? $timeout : null; try { - $feed = self::addFeed($url, '', $cat, null, $http_auth, $attributes); + $feed = self::addFeed($url, '', $cat, '', $http_auth, $attributes); } catch (FreshRSS_BadUrl_Exception $e) { // Given url was not a valid url! Minz_Log::warning($e->getMessage()); @@ -202,7 +202,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } catch (FreshRSS_AlreadySubscribed_Exception $e) { return Minz_Request::bad(_t('feedback.sub.feed.already_subscribed', $e->feedName()), $url_redirect); } catch (FreshRSS_FeedNotAdded_Exception $e) { - return Minz_Request::bad(_t('feedback.sub.feed.not_added', $e->feedName()), $url_redirect); + return Minz_Request::bad(_t('feedback.sub.feed.not_added', $e->url()), $url_redirect); } // Entries are in DB, we redirect to feed configuration page. @@ -296,7 +296,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $updated_feeds = 0; $nb_new_articles = 0; foreach ($feeds as $feed) { - /** @var FreshRSS_Feed $feed */ + /** @var FreshRSS_Feed|null $feed */ $feed = Minz_ExtensionManager::callHook('feed_before_actualize', $feed); if (null === $feed) { continue; @@ -874,14 +874,4 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $this->view->fatalError = _t('feedback.sub.feed.selector_preview.http_error'); } } - - /** - * This method update TTL values for feeds if needed. - * It changes the old default value (-2) to the new default value (0). - * It changes the old disabled value (-1) to the default disabled value. - */ - private function updateTTL() { - $feedDAO = FreshRSS_Factory::createFeedDao(); - $feedDAO->updateTTL(); - } } diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 0634bf54c..c19cf7831 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -3,9 +3,8 @@ /** * Controller to handle every import and export actions. */ -class FreshRSS_importExport_Controller extends Minz_ActionController { +class FreshRSS_importExport_Controller extends FreshRSS_ActionController { - private $catDAO; private $entryDAO; private $feedDAO; @@ -21,7 +20,6 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { require_once(LIB_PATH . '/lib_opml.php'); - $this->catDAO = FreshRSS_Factory::createCategoryDao(); $this->entryDAO = FreshRSS_Factory::createEntryDao(); $this->feedDAO = FreshRSS_Factory::createFeedDao(); } @@ -54,7 +52,6 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { public function importFile($name, $path, $username = null) { self::minimumMemory(256); - $this->catDAO = FreshRSS_Factory::createCategoryDao($username); $this->entryDAO = FreshRSS_Factory::createEntryDao($username); $this->feedDAO = FreshRSS_Factory::createFeedDao($username); @@ -492,9 +489,8 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { /** * This method import a JSON-based feed (Google Reader format). * - * @param array $origin represents a feed. - * @return FreshRSS_Feed if feed is in database at the end of the process, - * else null. + * @param array<string,string> $origin represents a feed. + * @return FreshRSS_Feed|null if feed is in database at the end of the process, else null. */ private function addFeedJson($origin) { $return = null; diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index eadfe252b..c6200f868 100755 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -3,7 +3,7 @@ /** * This class handles main actions of FreshRSS. */ -class FreshRSS_index_Controller extends Minz_ActionController { +class FreshRSS_index_Controller extends FreshRSS_ActionController { /** * This action only redirect on the default view mode (normal or global) diff --git a/app/Controllers/javascriptController.php b/app/Controllers/javascriptController.php index 4a79da27a..3eaae486a 100755 --- a/app/Controllers/javascriptController.php +++ b/app/Controllers/javascriptController.php @@ -1,6 +1,6 @@ <?php -class FreshRSS_javascript_Controller extends Minz_ActionController { +class FreshRSS_javascript_Controller extends FreshRSS_ActionController { public function firstAction() { $this->view->_layout(false); } @@ -36,7 +36,7 @@ class FreshRSS_javascript_Controller extends Minz_ActionController { if (strlen($s) >= 60) { //CRYPT_BLOWFISH Salt: "$2a$", a two digit cost parameter, "$", and 22 characters from the alphabet "./0-9A-Za-z". $this->view->salt1 = substr($s, 0, 29); - $this->view->nonce = sha1($salt . uniqid(mt_rand(), true)); + $this->view->nonce = sha1($salt . uniqid('' . mt_rand(), true)); Minz_Session::_param('nonce', $this->view->nonce); return; //Success } @@ -52,6 +52,6 @@ class FreshRSS_javascript_Controller extends Minz_ActionController { for ($i = 22; $i > 0; $i--) { $this->view->salt1 .= $alphabet[mt_rand(0, 63)]; } - $this->view->nonce = sha1(mt_rand()); + $this->view->nonce = sha1('' . mt_rand()); } } diff --git a/app/Controllers/statsController.php b/app/Controllers/statsController.php index 980f3532d..2815af4a5 100644 --- a/app/Controllers/statsController.php +++ b/app/Controllers/statsController.php @@ -3,7 +3,7 @@ /** * Controller to handle application statistics. */ -class FreshRSS_stats_Controller extends Minz_ActionController { +class FreshRSS_stats_Controller extends FreshRSS_ActionController { /** * This action is called before every other action in that class. It is diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php index c01e01843..7545035cc 100644 --- a/app/Controllers/subscriptionController.php +++ b/app/Controllers/subscriptionController.php @@ -3,7 +3,7 @@ /** * Controller to handle subscription actions. */ -class FreshRSS_subscription_Controller extends Minz_ActionController { +class FreshRSS_subscription_Controller extends FreshRSS_ActionController { /** * This action is called before every other action in that class. It is * the common boiler plate for every action. It is triggered by the @@ -175,7 +175,7 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { if ($enableRetentionPeriod = Minz_Request::paramBoolean('enable_keep_period')) { $keepPeriod = FreshRSS_Feed::ARCHIVING_RETENTION_PERIOD; if (is_numeric(Minz_Request::param('keep_period_count')) && preg_match('/^PT?1[YMWDH]$/', Minz_Request::param('keep_period_unit'))) { - $keepPeriod = str_replace(1, Minz_Request::param('keep_period_count'), Minz_Request::param('keep_period_unit')); + $keepPeriod = str_replace('1', Minz_Request::param('keep_period_count'), Minz_Request::param('keep_period_unit')); } } else { $keepPeriod = false; @@ -244,7 +244,7 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { if ($enableRetentionPeriod = Minz_Request::paramBoolean('enable_keep_period')) { $keepPeriod = FreshRSS_Feed::ARCHIVING_RETENTION_PERIOD; if (is_numeric(Minz_Request::param('keep_period_count')) && preg_match('/^PT?1[YMWDH]$/', Minz_Request::param('keep_period_unit'))) { - $keepPeriod = str_replace(1, Minz_Request::param('keep_period_count'), Minz_Request::param('keep_period_unit')); + $keepPeriod = str_replace('1', Minz_Request::param('keep_period_count'), Minz_Request::param('keep_period_unit')); } } else { $keepPeriod = false; diff --git a/app/Controllers/tagController.php b/app/Controllers/tagController.php index 077be9700..8f399988d 100644 --- a/app/Controllers/tagController.php +++ b/app/Controllers/tagController.php @@ -3,7 +3,7 @@ /** * Controller to handle every tag actions. */ -class FreshRSS_tag_Controller extends Minz_ActionController { +class FreshRSS_tag_Controller extends FreshRSS_ActionController { /** * JavaScript request or not. diff --git a/app/Controllers/updateController.php b/app/Controllers/updateController.php index 16ab7e427..0f67fe64c 100644 --- a/app/Controllers/updateController.php +++ b/app/Controllers/updateController.php @@ -1,6 +1,6 @@ <?php -class FreshRSS_update_Controller extends Minz_ActionController { +class FreshRSS_update_Controller extends FreshRSS_ActionController { public static function isGit() { return is_dir(FRESHRSS_PATH . '/.git/'); @@ -261,7 +261,7 @@ class FreshRSS_update_Controller extends Minz_ActionController { Minz_Request::forward(array( 'c' => 'update', 'a' => 'apply', - 'params' => array('post_conf' => true) + 'params' => array('post_conf' => '1') ), true); } else { Minz_Request::bad(_t('feedback.update.error', $res), [ 'c' => 'update', 'a' => 'index' ]); diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php index b1f34ce61..c5e1b30ab 100644 --- a/app/Controllers/userController.php +++ b/app/Controllers/userController.php @@ -3,7 +3,7 @@ /** * Controller to handle user actions. */ -class FreshRSS_user_Controller extends Minz_ActionController { +class FreshRSS_user_Controller extends FreshRSS_ActionController { /** * The username is also used as folder name, file name, and part of SQL table name. * '_' is a reserved internal username. @@ -29,7 +29,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { if (FreshRSS_Context::$system_conf->force_email_validation) { $salt = FreshRSS_Context::$system_conf->salt; - $userConfig->email_validation_token = sha1($salt . uniqid(mt_rand(), true)); + $userConfig->email_validation_token = sha1($salt . uniqid('' . mt_rand(), true)); $mailer = new FreshRSS_User_Mailer(); $mailer->send_email_need_validation($user, $userConfig); } @@ -536,7 +536,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { if (Minz_Request::isPost()) { $ok = true; - if ($ok && $self_deletion) { + if ($self_deletion) { // We check the password if it's a self-destruction $nonce = Minz_Session::param('nonce'); $challenge = Minz_Request::param('challenge', ''); diff --git a/app/Exceptions/FeedNotAddedException.php b/app/Exceptions/FeedNotAddedException.php index 350a17c56..59fa74b16 100644 --- a/app/Exceptions/FeedNotAddedException.php +++ b/app/Exceptions/FeedNotAddedException.php @@ -1,14 +1,14 @@ <?php class FreshRSS_FeedNotAdded_Exception extends Exception { - private $feedName = ''; + private $url = ''; - public function __construct($url, $feedName) { + public function __construct($url) { parent::__construct('Feed not added! ' . $url, 2147); - $this->feedName = $feedName; + $this->url = $url; } - public function feedName() { - return $this->feedName; + public function url() { + return $this->url; } } diff --git a/app/Mailers/UserMailer.php b/app/Mailers/UserMailer.php index f1618303a..4450bd96c 100644 --- a/app/Mailers/UserMailer.php +++ b/app/Mailers/UserMailer.php @@ -4,6 +4,12 @@ * Manage the emails sent to the users. */ class FreshRSS_User_Mailer extends Minz_Mailer { + + /** + * @var FreshRSS_View + */ + protected $view; + public function send_email_need_validation($username, $user_config) { Minz_Translate::reset($user_config->language); diff --git a/app/Models/ActionController.php b/app/Models/ActionController.php new file mode 100644 index 000000000..2e0aaa730 --- /dev/null +++ b/app/Models/ActionController.php @@ -0,0 +1,9 @@ +<?php + +class FreshRSS_ActionController extends Minz_ActionController { + + /** + * @var FreshRSS_View + */ + protected $view; +} diff --git a/app/Models/Auth.php b/app/Models/Auth.php index 04bd4291f..7259025b3 100644 --- a/app/Models/Auth.php +++ b/app/Models/Auth.php @@ -215,7 +215,7 @@ class FreshRSS_Auth { $csrf = Minz_Session::param('csrf'); if ($csrf == '') { $salt = FreshRSS_Context::$system_conf->salt; - $csrf = sha1($salt . uniqid(mt_rand(), true)); + $csrf = sha1($salt . uniqid('' . mt_rand(), true)); Minz_Session::_param('csrf', $csrf); } return $csrf; diff --git a/app/Models/ConfigurationSetter.php b/app/Models/ConfigurationSetter.php index 3c07db4a0..336a93351 100644 --- a/app/Models/ConfigurationSetter.php +++ b/app/Models/ConfigurationSetter.php @@ -371,6 +371,7 @@ class FreshRSS_ConfigurationSetter { $value = intval($value); $limits = $limits_keys[$key]; + // @phpstan-ignore-next-line if ((!isset($limits['min']) || $value >= $limits['min']) && (!isset($limits['max']) || $value <= $limits['max']) ) { diff --git a/app/Models/Context.php b/app/Models/Context.php index 6b2043bd3..62dc53774 100644 --- a/app/Models/Context.php +++ b/app/Models/Context.php @@ -5,8 +5,17 @@ * useful functions associated to the current view state. */ class FreshRSS_Context { + + /** + * @var FreshRSS_UserConfiguration|null + */ public static $user_conf = null; + + /** + * @var FreshRSS_SystemConfiguration|null + */ public static $system_conf = null; + public static $categories = array(); public static $tags = array(); @@ -49,7 +58,11 @@ class FreshRSS_Context { if ($reload || FreshRSS_Context::$system_conf == null) { //TODO: Keep in session what we need instead of always reloading from disk Minz_Configuration::register('system', DATA_PATH . '/config.php', FRESHRSS_PATH . '/config.default.php'); - FreshRSS_Context::$system_conf = Minz_Configuration::get('system'); + /** + * @var FreshRSS_SystemConfiguration $system_conf + */ + $system_conf = Minz_Configuration::get('system'); + FreshRSS_Context::$system_conf = $system_conf; // Register the configuration setter for the system configuration $configurationSetter = new FreshRSS_ConfigurationSetter(); FreshRSS_Context::$system_conf->_configurationSetter($configurationSetter); @@ -80,7 +93,11 @@ class FreshRSS_Context { FreshRSS_Context::$system_conf->configurationSetter()); Minz_Session::_param('currentUser', $username); - FreshRSS_Context::$user_conf = Minz_Configuration::get('user'); + /** + * @var FreshRSS_UserConfiguration $user_conf + */ + $user_conf = Minz_Configuration::get('user'); + FreshRSS_Context::$user_conf = $user_conf; } catch (Exception $ex) { Minz_Log::warning($ex->getMessage(), USERS_PATH . '/_/log.txt'); } diff --git a/app/Models/Entry.php b/app/Models/Entry.php index d3aa13327..cc1f4d9bc 100644 --- a/app/Models/Entry.php +++ b/app/Models/Entry.php @@ -260,7 +260,7 @@ class FreshRSS_Entry extends Minz_Model { } foreach ($booleanSearch->searches() as $filter) { $ok = true; - if ($ok && $filter->getMinDate()) { + if ($filter->getMinDate()) { $ok &= strnatcmp($this->id, $filter->getMinDate() . '000000') >= 0; } if ($ok && $filter->getNotMinDate()) { @@ -451,12 +451,18 @@ class FreshRSS_Entry extends Minz_Model { Minz_Log::warning('Error fetching content: HTTP code ' . $c_status . ': ' . $c_error . ' ' . $url); } - if ($html) { + if (is_string($html) && strlen($html) > 0) { require_once(LIB_PATH . '/lib_phpQuery.php'); + /** + * @var phpQueryObject @doc + */ $doc = phpQuery::newDocument($html); if ($maxRedirs > 0) { //Follow any HTML redirection + /** + * @var phpQueryObject @metas + */ $metas = $doc->find('meta[http-equiv][content]'); foreach ($metas as $meta) { if (strtolower(trim($meta->getAttribute('http-equiv'))) === 'refresh') { @@ -470,6 +476,9 @@ class FreshRSS_Entry extends Minz_Model { } } + /** + * @var phpQueryObject @content + */ $content = $doc->find($path); $html = trim(sanitizeHTML($content->__toString(), $url)); phpQuery::unloadDocuments(); diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index 2e4f52d0b..ff5777bb0 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -310,7 +310,7 @@ SQL; $hasWhere = false; $values = array(); if ($feedId !== false) { - $sql .= $hasWhere ? ' AND' : ' WHERE'; + $sql .= ' WHERE'; $hasWhere = true; $sql .= ' f.id=?'; $values[] = $feedId; @@ -342,7 +342,7 @@ SQL; * * @param integer|array $ids * @param boolean $is_read - * @return integer affected rows + * @return integer|false affected rows */ public function markRead($ids, $is_read = true) { FreshRSS_UserDAO::touch(); @@ -415,7 +415,7 @@ SQL; * @param integer $idMax fail safe article ID * @param boolean $onlyFavorites * @param integer $priorityMin - * @return integer affected rows + * @return integer|false affected rows */ public function markReadEntries($idMax = 0, $onlyFavorites = false, $priorityMin = 0, $filters = null, $state = 0, $is_read = true) { FreshRSS_UserDAO::touch(); @@ -458,7 +458,7 @@ SQL; * * @param integer $id category ID * @param integer $idMax fail safe article ID - * @return integer affected rows + * @return integer|false affected rows */ public function markReadCat($id, $idMax = 0, $filters = null, $state = 0, $is_read = true) { FreshRSS_UserDAO::touch(); @@ -496,7 +496,7 @@ SQL; * * @param integer $id_feed feed ID * @param integer $idMax fail safe article ID - * @return integer affected rows + * @return integer|false affected rows */ public function markReadFeed($id_feed, $idMax = 0, $filters = null, $state = 0, $is_read = true) { FreshRSS_UserDAO::touch(); @@ -544,7 +544,7 @@ SQL; * Mark all the articles in a tag as read. * @param integer $id tag ID, or empty for targetting any tag * @param integer $idMax max article ID - * @return integer affected rows + * @return integer|false affected rows */ public function markReadTag($id = 0, $idMax = 0, $filters = null, $state = 0, $is_read = true) { FreshRSS_UserDAO::touch(); diff --git a/app/Models/EntryDAOSQLite.php b/app/Models/EntryDAOSQLite.php index 65df483ff..649536bdf 100644 --- a/app/Models/EntryDAOSQLite.php +++ b/app/Models/EntryDAOSQLite.php @@ -77,7 +77,7 @@ DROP TABLE IF EXISTS `tmp`; $hasWhere = false; $values = array(); if ($feedId !== false) { - $sql .= $hasWhere ? ' AND' : ' WHERE'; + $sql .= ' WHERE'; $hasWhere = true; $sql .= ' id=?'; $values[] = $feedId; @@ -109,7 +109,7 @@ DROP TABLE IF EXISTS `tmp`; * * @param integer|array $ids * @param boolean $is_read - * @return integer affected rows + * @return integer|false affected rows */ public function markRead($ids, $is_read = true) { FreshRSS_UserDAO::touch(); @@ -169,7 +169,7 @@ DROP TABLE IF EXISTS `tmp`; * @param integer $idMax fail safe article ID * @param boolean $onlyFavorites * @param integer $priorityMin - * @return integer affected rows + * @return integer|false affected rows */ public function markReadEntries($idMax = 0, $onlyFavorites = false, $priorityMin = 0, $filters = null, $state = 0, $is_read = true) { FreshRSS_UserDAO::touch(); @@ -210,7 +210,7 @@ DROP TABLE IF EXISTS `tmp`; * * @param integer $id category ID * @param integer $idMax fail safe article ID - * @return integer affected rows + * @return integer|false affected rows */ public function markReadCat($id, $idMax = 0, $filters = null, $state = 0, $is_read = true) { FreshRSS_UserDAO::touch(); @@ -244,7 +244,7 @@ DROP TABLE IF EXISTS `tmp`; * Mark all the articles in a tag as read. * @param integer $id tag ID, or empty for targetting any tag * @param integer $idMax max article ID - * @return integer affected rows + * @return integer|false affected rows */ public function markReadTag($id = 0, $idMax = 0, $filters = null, $state = 0, $is_read = true) { FreshRSS_UserDAO::touch(); diff --git a/app/Models/Feed.php b/app/Models/Feed.php index 3dc965b32..972983384 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -259,6 +259,7 @@ class FreshRSS_Feed extends Minz_Model { public function load($loadDetails = false, $noCache = false) { if ($this->url !== null) { + // @phpstan-ignore-next-line if (CACHE_PATH === false) { throw new Minz_FileNotExistException( 'CACHE_PATH', @@ -462,10 +463,10 @@ class FreshRSS_Feed extends Minz_Model { $entry = new FreshRSS_Entry( $this->id(), $hasBadGuids ? '' : $guid, - $title === null ? '' : $title, + $title == '' ? '' : $title, $author_names, - $content === null ? '' : $content, - $link === null ? '' : $link, + $content == '' ? '' : $content, + $link == '' ? '' : $link, $date ? $date : time() ); $entry->_tags($tags); diff --git a/app/Models/FormAuth.php b/app/Models/FormAuth.php index 5211fd5d1..d6da637d1 100644 --- a/app/Models/FormAuth.php +++ b/app/Models/FormAuth.php @@ -50,7 +50,7 @@ class FreshRSS_FormAuth { public static function makeCookie($username, $password_hash) { do { - $token = sha1(FreshRSS_Context::$system_conf->salt . $username . uniqid(mt_rand(), true)); + $token = sha1(FreshRSS_Context::$system_conf->salt . $username . uniqid('' . mt_rand(), true)); $token_file = DATA_PATH . '/tokens/' . $token . '.txt'; } while (file_exists($token_file)); diff --git a/app/Models/ReadingMode.php b/app/Models/ReadingMode.php index 06af1704c..ddb413315 100644 --- a/app/Models/ReadingMode.php +++ b/app/Models/ReadingMode.php @@ -81,14 +81,14 @@ class FreshRSS_ReadingMode { } /** - * @return string + * @return array<string> */ public function getUrlParams() { return $this->urlParams; } /** - * @param string $urlParams + * @param array<string> $urlParams * @return FreshRSS_ReadingMode */ public function setUrlParams($urlParams) { diff --git a/app/Models/Share.php b/app/Models/Share.php index 695b16eca..0a341fa55 100644 --- a/app/Models/Share.php +++ b/app/Models/Share.php @@ -11,7 +11,7 @@ class FreshRSS_Share { /** * Register a new sharing option. - * @param array<string,string> $share_options is an array defining the share option. + * @param array<string,string|array<string>> $share_options is an array defining the share option. */ public static function register($share_options) { $type = $share_options['type']; diff --git a/app/Models/StatsDAO.php b/app/Models/StatsDAO.php index 33e5426b5..612fe5cab 100644 --- a/app/Models/StatsDAO.php +++ b/app/Models/StatsDAO.php @@ -133,7 +133,7 @@ SQL; * * @param string $period format string to use for grouping * @param integer $feed id - * @return array + * @return array<int,int> */ protected function calculateEntryRepartitionPerFeedPerPeriod($period, $feed = null) { $restrict = ''; @@ -178,7 +178,7 @@ SQL; * Calculates the average number of article per hour per feed * * @param integer $feed id - * @return integer + * @return float */ public function calculateEntryAveragePerFeedPerHour($feed = null) { return $this->calculateEntryAveragePerFeedPerPeriod(1 / 24, $feed); @@ -188,7 +188,7 @@ SQL; * Calculates the average number of article per day of week per feed * * @param integer $feed id - * @return integer + * @return float */ public function calculateEntryAveragePerFeedPerDayOfWeek($feed = null) { return $this->calculateEntryAveragePerFeedPerPeriod(7, $feed); @@ -198,7 +198,7 @@ SQL; * Calculates the average number of article per month per feed * * @param integer $feed id - * @return integer + * @return float */ public function calculateEntryAveragePerFeedPerMonth($feed = null) { return $this->calculateEntryAveragePerFeedPerPeriod(30, $feed); @@ -209,7 +209,7 @@ SQL; * * @param float $period number used to divide the number of day in the period * @param integer $feed id - * @return integer + * @return float */ protected function calculateEntryAveragePerFeedPerPeriod($period, $feed = null) { $restrict = ''; @@ -337,7 +337,7 @@ SQL; /** * Gets days ready for graphs * - * @return string + * @return array<string> */ public function getDays() { return $this->convertToTranslatedJson(array( @@ -354,7 +354,7 @@ SQL; /** * Gets months ready for graphs * - * @return string + * @return array<string> */ public function getMonths() { return $this->convertToTranslatedJson(array( @@ -377,7 +377,7 @@ SQL; * Translates array content * * @param array $data - * @return array + * @return array<string> */ private function convertToTranslatedJson($data = array()) { $translated = array_map(function($a) { diff --git a/app/Models/StatsDAOPGSQL.php b/app/Models/StatsDAOPGSQL.php index f36d29770..85f9d63f3 100644 --- a/app/Models/StatsDAOPGSQL.php +++ b/app/Models/StatsDAOPGSQL.php @@ -6,7 +6,7 @@ class FreshRSS_StatsDAOPGSQL extends FreshRSS_StatsDAO { * Calculates the number of article per hour of the day per feed * * @param integer $feed id - * @return string + * @return array */ public function calculateEntryRepartitionPerFeedPerHour($feed = null) { return $this->calculateEntryRepartitionPerFeedPerPeriod('hour', $feed); @@ -16,7 +16,7 @@ class FreshRSS_StatsDAOPGSQL extends FreshRSS_StatsDAO { * Calculates the number of article per day of week per feed * * @param integer $feed id - * @return string + * @return array */ public function calculateEntryRepartitionPerFeedPerDayOfWeek($feed = null) { return $this->calculateEntryRepartitionPerFeedPerPeriod('day', $feed); @@ -26,7 +26,7 @@ class FreshRSS_StatsDAOPGSQL extends FreshRSS_StatsDAO { * Calculates the number of article per month per feed * * @param integer $feed - * @return string + * @return array */ public function calculateEntryRepartitionPerFeedPerMonth($feed = null) { return $this->calculateEntryRepartitionPerFeedPerPeriod('month', $feed); @@ -37,7 +37,7 @@ class FreshRSS_StatsDAOPGSQL extends FreshRSS_StatsDAO { * * @param string $period format string to use for grouping * @param integer $feed id - * @return string + * @return array<int,int> */ protected function calculateEntryRepartitionPerFeedPerPeriod($period, $feed = null) { $restrict = ''; diff --git a/app/Models/SystemConfiguration.php b/app/Models/SystemConfiguration.php new file mode 100644 index 000000000..3b07bc9ff --- /dev/null +++ b/app/Models/SystemConfiguration.php @@ -0,0 +1,28 @@ +<?php + +/** + * @property bool $allow_anonymous + * @property bool $allow_anonymous_refresh + * @property-read bool $allow_referrer + * @property-read bool $allow_robots + * @property bool $api_enabled + * @property string $archiving + * @property string $auth_type + * @property string $auto_update_url + * @property-read array<int,mixed> $curl_options + * @property string $default_user + * @property string $email_validation_token + * @property bool $force_email_validation + * @property-read bool $http_auth_auto_register + * @property-read string $http_auth_auto_register_email_field + * @property-read string $language + * @property array<string,int> $limits + * @property-read string $meta_description + * @property-read bool $pubsubhubbub_enabled + * @property-read string $salt + * @property-read bool $simplepie_syslog_enabled + * @property string $unsafe_autologin_enabled + */ +class FreshRSS_SystemConfiguration extends Minz_Configuration { + +} diff --git a/app/Models/TagDAO.php b/app/Models/TagDAO.php index a0e492739..2b24921a2 100644 --- a/app/Models/TagDAO.php +++ b/app/Models/TagDAO.php @@ -74,8 +74,8 @@ SQL; * @param FreshRSS_Tag $tag */ public function addTagObject($tag) { - $tag = $this->searchByName($tag->name()); - if (!$tag) { + $tag0 = $this->searchByName($tag->name()); + if (!$tag0) { $values = array( 'name' => $tag->name(), 'attributes' => $tag->attributes(), @@ -198,7 +198,7 @@ SQL; } /** - * @return FreshRSS_Tag + * @return FreshRSS_Tag|null */ public function searchById($id) { $sql = 'SELECT * FROM `_tag` WHERE id=?'; @@ -211,7 +211,7 @@ SQL; } /** - * @return FreshRSS_Tag + * @return FreshRSS_Tag|null */ public function searchByName($name) { $sql = 'SELECT * FROM `_tag` WHERE name=?'; diff --git a/app/Models/UserConfiguration.php b/app/Models/UserConfiguration.php new file mode 100644 index 000000000..864bf4ec8 --- /dev/null +++ b/app/Models/UserConfiguration.php @@ -0,0 +1,64 @@ +<?php + +/** + * @property string $apiPasswordHash + * @property array<string,mixed> $archiving + * @property bool $auto_load_more + * @property bool $auto_remove_article + * @property bool $bottomline_date + * @property bool $bottomline_favorite + * @property bool $bottomline_link + * @property bool $bottomline_read + * @property bool $bottomline_sharing + * @property bool $bottomline_tags + * @property string $content_width + * @property-read string $default_state + * @property string $default_view + * @property string|bool $display_categories + * @property bool $display_posts + * @property string $email_validation_token + * @property-read string $enabled + * @property string $feverKey + * @property bool $hide_read_feeds + * @property int $html5_notif_timeout + * @property-read string $is_admin + * @property int|null $keep_history_default + * @property string $language + * @property bool $lazyload + * @property string $mail_login + * @property bool $mark_updated_article_unread + * @property array<string,bool> $mark_when + * @property int $max_posts_per_rss + * @property-read array<string,int> $limits + * @property int|null $old_entries + * @property bool $onread_jump_next + * @property string $passwordHash + * @property int $posts_per_page + * @property array<int,array<string,string>> $queries + * @property bool $reading_confirm + * @property int $since_hours_posts_per_rss + * @property bool $show_fav_unread + * @property bool $show_favicons + * @property bool $show_nav_buttons + * @property string $sort_order + * @property array<string,array<string>> $sharing + * @property array<string,string> $shortcuts + * @property bool $sides_close_article + * @property bool $sticky_post + * @property string $theme + * @property string $token + * @property bool $topline_date + * @property bool $topline_display_authors + * @property bool $topline_favorite + * @property bool $topline_link + * @property bool $topline_read + * @property bool $topline_summary + * @property string $topline_thumbnail + * @property int $ttl_default + * @property-read bool $unsafe_autologin_enabled + * @property string $view_mode + * @property array<string,mixed> $volatile + */ +class FreshRSS_UserConfiguration extends Minz_Configuration { + +} diff --git a/app/Models/UserQuery.php b/app/Models/UserQuery.php index 88ddd3629..7f8aa07ef 100644 --- a/app/Models/UserQuery.php +++ b/app/Models/UserQuery.php @@ -22,7 +22,7 @@ class FreshRSS_UserQuery { private $tag_dao; /** - * @param array $query + * @param array<string,string> $query * @param FreshRSS_Searchable $feed_dao * @param FreshRSS_Searchable $category_dao */ @@ -55,7 +55,7 @@ class FreshRSS_UserQuery { /** * Convert the current object to an array. * - * @return array + * @return array<string,string> */ public function toArray() { return array_filter(array( diff --git a/app/Models/View.php b/app/Models/View.php index 22bc2c49a..e3a591155 100644 --- a/app/Models/View.php +++ b/app/Models/View.php @@ -4,9 +4,11 @@ class FreshRSS_View extends Minz_View { // Main views public $callbackBeforeEntries; + public $callbackBeforeFeeds; public $callbackBeforePagination; public $categories; public $category; + public $current_user; public $entries; public $entry; public $feed; @@ -33,6 +35,7 @@ class FreshRSS_View extends Minz_View { public $status_files; public $status_php; public $update_to_apply; + public $status_database; // Archiving public $nb_total; @@ -46,12 +49,19 @@ class FreshRSS_View extends Minz_View { public $list_keys; // User queries + /** + * @var array<int,FreshRSS_UserQuery> + */ public $queries; + /** + * @var FreshRSS_UserQuery|null + */ public $query; // Export / Import public $content; public $entriesRaw; + public $entriesId; public $entryIdsTagNames; public $list_title; public $queryId; @@ -87,6 +97,7 @@ class FreshRSS_View extends Minz_View { public $selectorSuccess; // Extensions + public $available_extensions; public $ext_details; public $extension_list; public $extension; @@ -95,6 +106,7 @@ class FreshRSS_View extends Minz_View { // Errors public $code; public $errorMessage; + public $message; // Statistics public $average; diff --git a/app/Services/ImportService.php b/app/Services/ImportService.php index 5db640455..4cc38c15c 100644 --- a/app/Services/ImportService.php +++ b/app/Services/ImportService.php @@ -4,9 +4,6 @@ * Provide methods to import files. */ class FreshRSS_Import_Service { - /** @var string */ - private $username; - /** @var FreshRSS_CategoryDAO */ private $catDAO; @@ -21,7 +18,6 @@ class FreshRSS_Import_Service { public function __construct($username) { require_once(LIB_PATH . '/lib_opml.php'); - $this->username = $username; $this->catDAO = FreshRSS_Factory::createCategoryDao($username); $this->feedDAO = FreshRSS_Factory::createFeedDao($username); } diff --git a/app/actualize_script.php b/app/actualize_script.php index 721376f62..e3ee5a5e5 100755 --- a/app/actualize_script.php +++ b/app/actualize_script.php @@ -27,9 +27,11 @@ define('SIMPLEPIE_SYSLOG_ENABLED', FreshRSS_Context::$system_conf->simplepie_sys */ function notice($message) { Minz_Log::notice($message, ADMIN_LOG); + // @phpstan-ignore-next-line if (!COPY_LOG_TO_SYSLOG && SIMPLEPIE_SYSLOG_ENABLED) { syslog(LOG_NOTICE, $message); } + // @phpstan-ignore-next-line if (defined('STDOUT') && !COPY_SYSLOG_TO_STDERR) { fwrite(STDOUT, $message . "\n"); //Unbuffered } diff --git a/app/install.php b/app/install.php index 295be8b76..c9faffd4c 100644 --- a/app/install.php +++ b/app/install.php @@ -276,6 +276,9 @@ function freshrss_already_installed() { $system_conf = null; try { Minz_Configuration::register('system', $conf_path); + /** + * @var FreshRSS_SystemConfiguration $system_conf + */ $system_conf = Minz_Configuration::get('system'); } catch (Minz_FileNotExistException $e) { return false; diff --git a/app/views/configure/queries.phtml b/app/views/configure/queries.phtml index 3f15f299b..3e4b3684b 100644 --- a/app/views/configure/queries.phtml +++ b/app/views/configure/queries.phtml @@ -16,7 +16,7 @@ <div class="form-group" id="query-group-<?= $key ?>" draggable="true"> <div class="box"> <div class="box-title"> - <a class="configure open-slider" href="<?= _url('configure', 'query', 'id', $key) ?>"><?= _i('configure') ?></a><?= $query->getName() ?> + <a class="configure open-slider" href="<?= _url('configure', 'query', 'id', '' . $key) ?>"><?= _i('configure') ?></a><?= $query->getName() ?> <input type="hidden" id="queries_<?= $key ?>_name" name="queries[<?= $key ?>][name]" value="<?= $query->getName() ?>"/> <input type="hidden" id="queries_<?= $key ?>_url" name="queries[<?= $key ?>][url]" value="<?= $query->getUrl() ?>"/> <input type="hidden" id="queries_<?= $key ?>_search" name="queries[<?= $key ?>][search]" value="<?= urlencode($query->getSearch()) ?>"/> @@ -66,7 +66,7 @@ </a> <div id="slider"<?= $class ?>> <?php - if (isset($this->query)) { + if ($this->query != null) { $this->renderHelper('configure/query'); } ?> diff --git a/app/views/helpers/index/normal/entry_bottom.phtml b/app/views/helpers/index/normal/entry_bottom.phtml index 07e68ed92..5f105c6c9 100644 --- a/app/views/helpers/index/normal/entry_bottom.phtml +++ b/app/views/helpers/index/normal/entry_bottom.phtml @@ -35,6 +35,7 @@ ?></li><?php } } + // @phpstan-ignore-next-line if ($bottomline_labels) { ?><li class="item"> <div class="dropdown dynamictags"> diff --git a/app/views/helpers/pagination.phtml b/app/views/helpers/pagination.phtml index 9b249762c..eed4f5dc2 100755 --- a/app/views/helpers/pagination.phtml +++ b/app/views/helpers/pagination.phtml @@ -20,7 +20,7 @@ <?php $hasAccess = FreshRSS_Auth::hasAccess(); -if ($url_mark_read && $hasAccess) { ?> +if ($hasAccess) { ?> <form id="mark-read-pagination" method="post"> <input type="hidden" name="_csrf" value="<?= FreshRSS_Auth::csrfToken() ?>" /> <?php } else { ?> @@ -32,7 +32,7 @@ if ($url_mark_read && $hasAccess) { ?> <a id="load_more" href="<?= Minz_Url::display($url_next) ?>"> <?= _t('gen.pagination.load_more') ?> </a> - <?php } elseif ($url_mark_read && $hasAccess) { ?> + <?php } elseif ($hasAccess) { ?> <button id="bigMarkAsRead" class="as-link <?= FreshRSS_Context::$user_conf->reading_confirm ? 'confirm" disabled="disabled' : '' ?>" form="mark-read-pagination" @@ -49,7 +49,7 @@ if ($url_mark_read && $hasAccess) { ?> <?php } ?> </li> </ul> -<?php if ($url_mark_read && $hasAccess) { ?> +<?php if ($hasAccess) { ?> </form> <?php } else {?> </div> diff --git a/app/views/index/rss.phtml b/app/views/index/rss.phtml index f0772cc86..eedb31fa4 100755 --- a/app/views/index/rss.phtml +++ b/app/views/index/rss.phtml @@ -3,7 +3,7 @@ <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"> <channel> <title><?= $this->rss_title ?></title> - <link><?= Minz_Url::display(null, 'html', true) ?></link> + <link><?= Minz_Url::display('', 'html', true) ?></link> <description><?= _t('index.feed.rss_of', $this->rss_title) ?></description> <pubDate><?= date('D, d M Y H:i:s O') ?></pubDate> <lastBuildDate><?= gmdate('D, d M Y H:i:s') ?> GMT</lastBuildDate> diff --git a/app/views/subscription/index.phtml b/app/views/subscription/index.phtml index e16d6ad95..92b1c7ec9 100644 --- a/app/views/subscription/index.phtml +++ b/app/views/subscription/index.phtml @@ -22,7 +22,7 @@ <?php if (!$this->onlyFeedsWithError && $this->signalError){ ?> <div> - <a class="btn" href="<?= _url('subscription', 'index', 'error', 1) ?>"><?= _i('look') ?> <?= _t('sub.feed.show.error') ?></a> + <a class="btn" href="<?= _url('subscription', 'index', 'error', '1') ?>"><?= _i('look') ?> <?= _t('sub.feed.show.error') ?></a> </div> <?php } ?> diff --git a/app/views/user/profile.phtml b/app/views/user/profile.phtml index 99ebcb326..5acb241ed 100644 --- a/app/views/user/profile.phtml +++ b/app/views/user/profile.phtml @@ -57,8 +57,7 @@ <label class="group-name" for="token"><?= _t('admin.auth.token') ?></label> <?php $token = FreshRSS_Context::$user_conf->token; ?> <div class="group-controls"> - <input type="text" id="token" name="token" value="<?= $token ?>" placeholder="<?= _t('gen.short.blank_to_disable') ?>"<?php - echo FreshRSS_Auth::accessNeedsAction() ? '' : ' disabled="disabled"'; ?> data-leave-validation="<?= $token ?>"/> + <input type="text" id="token" name="token" value="<?= $token ?>" placeholder="<?= _t('gen.short.blank_to_disable') ?>" data-leave-validation="<?= $token ?>"/> <p class="help"><?= _i('help') ?> <?= _t('admin.auth.token_help') ?></p> <kbd><?= Minz_Url::display(array('a' => 'rss', 'params' => array('user' => Minz_Session::param('currentUser'), 'token' => $token, 'hours' => FreshRSS_Context::$user_conf->since_hours_posts_per_rss)), 'html', true) ?></kbd> diff --git a/cli/i18n/I18nCompletionValidator.php b/cli/i18n/I18nCompletionValidator.php index 2cb71acd5..3287a2500 100644 --- a/cli/i18n/I18nCompletionValidator.php +++ b/cli/i18n/I18nCompletionValidator.php @@ -23,6 +23,9 @@ class I18nCompletionValidator implements I18nValidatorInterface { return $this->result; } + /** + * @param array<string>|null $ignore + */ public function validate($ignore) { foreach ($this->reference as $file => $data) { foreach ($data as $key => $value) { diff --git a/cli/i18n/I18nData.php b/cli/i18n/I18nData.php index 7e17c6c3c..2e5e373f8 100644 --- a/cli/i18n/I18nData.php +++ b/cli/i18n/I18nData.php @@ -130,7 +130,7 @@ class I18nData { if (array_key_exists($language, $this->data)) { throw new Exception('The selected language already exist.'); } - if (!is_string($reference) && !array_key_exists($reference, $this->data)) { + if (!is_string($reference) || !array_key_exists($reference, $this->data)) { $reference = static::REFERENCE_LANGUAGE; } $this->data[$language] = $this->data[$reference]; diff --git a/cli/i18n/I18nValidatorInterface.php b/cli/i18n/I18nValidatorInterface.php index edfe7aac0..80fcb22ad 100644 --- a/cli/i18n/I18nValidatorInterface.php +++ b/cli/i18n/I18nValidatorInterface.php @@ -19,7 +19,7 @@ interface I18nValidatorInterface { /** * Display the validation report. * - * @return array + * @return string */ public function displayReport(); diff --git a/docs/en/developers/03_Backend/05_Extensions.md b/docs/en/developers/03_Backend/05_Extensions.md index 81fd13ecb..1104b30f5 100644 --- a/docs/en/developers/03_Backend/05_Extensions.md +++ b/docs/en/developers/03_Backend/05_Extensions.md @@ -48,7 +48,7 @@ Code example: ```php <?php -class FreshRSS_hello_Controller extends Minz_ActionController { +class FreshRSS_hello_Controller extends FreshRSS_ActionController { public function indexAction() { $this->view->a_variable = 'FooBar'; } diff --git a/docs/fr/developers/03_Backend/05_Extensions.md b/docs/fr/developers/03_Backend/05_Extensions.md index 41571d7bb..98c2b9f7e 100644 --- a/docs/fr/developers/03_Backend/05_Extensions.md +++ b/docs/fr/developers/03_Backend/05_Extensions.md @@ -87,7 +87,7 @@ Exemple de code : ```php <?php -class FreshRSS_hello_Controller extends Minz_ActionController { +class FreshRSS_hello_Controller extends FreshRSS_ActionController { public function indexAction() { $this->view->a_variable = 'FooBar'; } diff --git a/docs/i18n/freshrss.fr.po b/docs/i18n/freshrss.fr.po index f6d36f925..04e530aac 100644 --- a/docs/i18n/freshrss.fr.po +++ b/docs/i18n/freshrss.fr.po @@ -1870,7 +1870,7 @@ msgstr "Exemple de code :" msgid "" "<?php\n" "\n" -"class FreshRSS_hello_Controller extends Minz_ActionController {\n" +"class FreshRSS_hello_Controller extends FreshRSS_ActionController {\n" "\tpublic function indexAction() {\n" "\t\t$this->view->a_variable = 'FooBar';\n" "\t}\n" @@ -1884,7 +1884,7 @@ msgid "" msgstr "" "<?php\n" "\n" -"class FreshRSS_hello_Controller extends Minz_ActionController {\n" +"class FreshRSS_hello_Controller extends FreshRSS_ActionController {\n" "\tpublic function indexAction() {\n" "\t\t$this->view->a_variable = 'FooBar';\n" "\t}\n" diff --git a/docs/i18n/templates/freshrss.pot b/docs/i18n/templates/freshrss.pot index dd1f0f6ce..6cb7d82e1 100644 --- a/docs/i18n/templates/freshrss.pot +++ b/docs/i18n/templates/freshrss.pot @@ -1489,7 +1489,7 @@ msgstr "" msgid "" "<?php\n" "\n" -"class FreshRSS_hello_Controller extends Minz_ActionController {\n" +"class FreshRSS_hello_Controller extends FreshRSS_ActionController {\n" "\tpublic function indexAction() {\n" "\t\t$this->view->a_variable = 'FooBar';\n" "\t}\n" diff --git a/lib/Minz/Configuration.php b/lib/Minz/Configuration.php index 539b1da62..403d6ccba 100644 --- a/lib/Minz/Configuration.php +++ b/lib/Minz/Configuration.php @@ -2,6 +2,14 @@ /** * Manage configuration for the application. + * @property-read string $base_url + * @property array<string|array<int,string>> $db + * @property-read string $disable_update + * @property-read string $environment + * @property-read array<string> $extensions_enabled + * @property-read string $mailer + * @property-read string $smtp + * @property string $title */ class Minz_Configuration { /** @@ -58,6 +66,8 @@ class Minz_Configuration { /** * The namespace of the current configuration. + * Unused. + * @phpstan-ignore-next-line */ private $namespace = ''; diff --git a/lib/Minz/Dispatcher.php b/lib/Minz/Dispatcher.php index f2664cbe0..3adcb2492 100644 --- a/lib/Minz/Dispatcher.php +++ b/lib/Minz/Dispatcher.php @@ -41,6 +41,7 @@ class Minz_Dispatcher { $this->createController (Minz_Request::controllerName ()); $this->controller->init (); $this->controller->firstAction (); + // @phpstan-ignore-next-line if (!self::$needsReset) { $this->launchAction ( Minz_Request::actionName () @@ -49,6 +50,7 @@ class Minz_Dispatcher { } $this->controller->lastAction (); + // @phpstan-ignore-next-line if (!self::$needsReset) { $this->controller->declareCspHeader(); $this->controller->view ()->build (); @@ -56,6 +58,7 @@ class Minz_Dispatcher { } catch (Minz_Exception $e) { throw $e; } + // @phpstan-ignore-next-line } while (self::$needsReset); } diff --git a/lib/Minz/Error.php b/lib/Minz/Error.php index 32de05f0c..bef273bda 100644 --- a/lib/Minz/Error.php +++ b/lib/Minz/Error.php @@ -13,7 +13,7 @@ class Minz_Error { /** * Permet de lancer une erreur * @param int $code le type de l'erreur, par défaut 404 (page not found) - * @param array<string> $logs logs d'erreurs découpés de la forme + * @param array<string>|array<string,array<string>> $logs logs d'erreurs découpés de la forme * > $logs['error'] * > $logs['warning'] * > $logs['notice'] @@ -50,7 +50,7 @@ class Minz_Error { /** * Permet de retourner les logs de façon à n'avoir que * ceux que l'on veut réellement - * @param array<string> $logs les logs rangés par catégories (error, warning, notice) + * @param array<string,string>|string $logs les logs rangés par catégories (error, warning, notice) * @return array<string> liste des logs, sans catégorie, en fonction de l'environment */ private static function processLogs ($logs) { diff --git a/lib/Minz/Extension.php b/lib/Minz/Extension.php index 82f9a0631..a35d7d8b6 100644 --- a/lib/Minz/Extension.php +++ b/lib/Minz/Extension.php @@ -192,7 +192,7 @@ abstract class Minz_Extension { * Register a new hook. * * @param string $hook_name the hook name (must exist). - * @param callable-string $hook_function the function name to call (must be callable). + * @param callable-string|array<string> $hook_function the function name to call (must be callable). */ public function registerHook($hook_name, $hook_function) { Minz_ExtensionManager::addHook($hook_name, $hook_function, $this); diff --git a/lib/Minz/ExtensionManager.php b/lib/Minz/ExtensionManager.php index 576064b35..2b42708f8 100644 --- a/lib/Minz/ExtensionManager.php +++ b/lib/Minz/ExtensionManager.php @@ -210,7 +210,7 @@ class Minz_ExtensionManager { * * The extension init() method will be called. * - * @param Minz_Extension $ext_name is the name of a valid extension present in $ext_list. + * @param string $ext_name is the name of a valid extension present in $ext_list. */ public static function enable($ext_name) { if (isset(self::$ext_list[$ext_name])) { @@ -295,8 +295,8 @@ class Minz_ExtensionManager { * array keys. * * @param string $hook_name the hook to call. - * @param array<mixed> $args additional parameters (for signature, please see self::$hook_list). - * @return mixed final result of the called hook. + * @param mixed $args additional parameters (for signature, please see self::$hook_list). + * @return mixed|null final result of the called hook. */ public static function callHook($hook_name, ...$args) { if (!isset(self::$hook_list[$hook_name])) { @@ -328,7 +328,7 @@ class Minz_ExtensionManager { * * @param string $hook_name is the hook to call. * @param mixed $arg is the argument to pass to the first extension hook. - * @return mixed final chained result of the hooks. If nothing is changed, + * @return mixed|null final chained result of the hooks. If nothing is changed, * the initial argument is returned. */ private static function callOneToOne($hook_name, $arg) { diff --git a/lib/Minz/Log.php b/lib/Minz/Log.php index 2b11f9b8b..e0e22e532 100644 --- a/lib/Minz/Log.php +++ b/lib/Minz/Log.php @@ -61,6 +61,7 @@ class Minz_Log { $log = '[' . date('r') . '] [' . $level_label . '] --- ' . $information . "\n"; + // @phpstan-ignore-next-line if (defined('COPY_LOG_TO_SYSLOG') && COPY_LOG_TO_SYSLOG) { syslog($level, '[' . $username . '] ' . trim($log)); } @@ -84,6 +85,7 @@ class Minz_Log { */ protected static function ensureMaxLogSize($file_name) { $maxSize = defined('MAX_LOG_SIZE') ? MAX_LOG_SIZE : 1048576; + // @phpstan-ignore-next-line if ($maxSize > 0 && @filesize($file_name) > $maxSize) { $fp = fopen($file_name, 'c+'); if ($fp && flock($fp, LOCK_EX)) { @@ -98,6 +100,7 @@ class Minz_Log { } else { throw new Minz_PermissionDeniedException($file_name, Minz_Exception::ERROR); } + // @phpstan-ignore-next-line if ($fp) { fclose($fp); } diff --git a/lib/Minz/Migrator.php b/lib/Minz/Migrator.php index d69a65422..637bfc3fa 100644 --- a/lib/Minz/Migrator.php +++ b/lib/Minz/Migrator.php @@ -160,7 +160,7 @@ class Minz_Migrator * * @param string $version The version of the migration (be careful, migrations * are sorted with the `strnatcmp` function) - * @param callback $callback The migration function to execute, it should + * @param callable $callback The migration function to execute, it should * return true on success and must return false * on error * diff --git a/lib/Minz/ModelPdo.php b/lib/Minz/ModelPdo.php index c03b28575..f183dae10 100644 --- a/lib/Minz/ModelPdo.php +++ b/lib/Minz/ModelPdo.php @@ -15,7 +15,6 @@ class Minz_ModelPdo { */ public static $usesSharedPdo = true; private static $sharedPdo = null; - private static $sharedPrefix; private static $sharedCurrentUser; protected $pdo; diff --git a/lib/Minz/Paginator.php b/lib/Minz/Paginator.php index 7504bf4ce..f7bb0cc4f 100644 --- a/lib/Minz/Paginator.php +++ b/lib/Minz/Paginator.php @@ -184,7 +184,7 @@ class Minz_Paginator { } private function _nbPage () { if ($this->nbItemsPerPage > 0) { - $this->nbPage = ceil ($this->nbItems () / $this->nbItemsPerPage); + $this->nbPage = (int)ceil($this->nbItems() / $this->nbItemsPerPage); } } public function _nbItems ($value) { diff --git a/lib/Minz/Request.php b/lib/Minz/Request.php index 7625cf5ed..e74f4f908 100644 --- a/lib/Minz/Request.php +++ b/lib/Minz/Request.php @@ -43,6 +43,7 @@ class Minz_Request { if (isset(self::$params[$key])) { $p = self::$params[$key]; $tp = trim($p); + // @phpstan-ignore-next-line if ($p === null || $tp === '' || $tp === 'null') { return null; } elseif ($p == false || $tp == '0' || $tp === 'false' || $tp === 'no') { @@ -328,7 +329,7 @@ class Minz_Request { /** * Relance une requête - * @param array<string,string> $url l'url vers laquelle est relancée la requête + * @param array<string,string|array<string,string>> $url l'url vers laquelle est relancée la requête * @param bool $redirect si vrai, force la redirection http * > sinon, le dispatcher recharge en interne */ @@ -359,7 +360,7 @@ class Minz_Request { /** * Wrappers good notifications + redirection * @param string $msg notification content - * @param array<string,string> $url url array to where we should be forwarded + * @param array<string,string|array<string,string>> $url url array to where we should be forwarded */ public static function good($msg, $url = array()) { Minz_Request::setGoodNotification($msg); @@ -369,7 +370,7 @@ class Minz_Request { /** * Wrappers bad notifications + redirection * @param string $msg notification content - * @param array<string,string> $url url array to where we should be forwarded + * @param array<string,string|array<string,mixed>> $url url array to where we should be forwarded */ public static function bad($msg, $url = array()) { Minz_Request::setBadNotification($msg); diff --git a/lib/Minz/Translate.php b/lib/Minz/Translate.php index 0659b0de2..4b860259e 100644 --- a/lib/Minz/Translate.php +++ b/lib/Minz/Translate.php @@ -85,7 +85,7 @@ class Minz_Translate { * Return the language to use in the application. * It returns the connected language if it exists then returns the first match from the * preferred languages then returns the default language - * @param string $user the connected user language (nullable) + * @param string|null $user the connected user language (nullable) * @param array<string> $preferred an array of the preferred languages * @param string $default the preferred language to use * @return string containing the language to use @@ -179,7 +179,7 @@ class Minz_Translate { /** * Translate a key into its corresponding value based on selected language. * @param string $key the key to translate. - * @param string $args additional parameters for variable keys. + * @param mixed $args additional parameters for variable keys. * @return string value corresponding to the key. * If no value is found, return the key itself. */ @@ -247,7 +247,7 @@ class Minz_Translate { /** * Alias for Minz_Translate::t() * @param string $key - * @param array<string> $args + * @param mixed $args */ function _t($key, ...$args) { return Minz_Translate::t($key, ...$args); diff --git a/lib/Minz/Url.php b/lib/Minz/Url.php index 59afff557..777962e25 100644 --- a/lib/Minz/Url.php +++ b/lib/Minz/Url.php @@ -6,13 +6,13 @@ class Minz_Url { /** * Affiche une Url formatée - * @param array<string,string> $url l'url à formater définie comme un tableau : + * @param string|array<string,string|array<string,mixed>> $url l'url à formater définie comme un tableau : * $url['c'] = controller * $url['a'] = action * $url['params'] = tableau des paramètres supplémentaires * ou comme une chaîne de caractère * @param string $encodage pour indiquer comment encoder les & (& ou & pour html) - * @param bool $absolute + * @param bool|string $absolute * @return string url formatée */ public static function display ($url = array (), $encodage = 'html', $absolute = false) { @@ -96,8 +96,8 @@ class Minz_Url { /** * Vérifie que les éléments du tableau représentant une url soit ok - * @param array<string,string>|string $url sous forme de tableau (sinon renverra directement $url) - * @return string url vérifié + * @param array<string,array<string,string>> $url sous forme de tableau + * @return array<string,array<string,string>> url vérifié */ public static function checkUrl ($url) { $url_checked = $url; @@ -121,7 +121,7 @@ class Minz_Url { /** * @param string $controller * @param string $action - * @param array<string,string> $args + * @param string $args */ function _url ($controller, $action, ...$args) { $nb_args = count($args); @@ -132,7 +132,8 @@ function _url ($controller, $action, ...$args) { $params = array (); for ($i = 0; $i < $nb_args; $i += 2) { - $params[$args[$i]] = $args[$i + 1]; + $arg = $args[$i]; + $params[$arg] = $args[$i + 1]; } return Minz_Url::display (array ('c' => $controller, 'a' => $action, 'params' => $params)); diff --git a/lib/Minz/View.php b/lib/Minz/View.php index bc38b8783..6b90b3c31 100644 --- a/lib/Minz/View.php +++ b/lib/Minz/View.php @@ -146,7 +146,7 @@ class Minz_View { /** * Choose the current view layout. - * @param string $layout the layout name to use, false to use no layouts. + * @param string|false $layout the layout name to use, false to use no layouts. */ public function _layout($layout) { if ($layout) { diff --git a/lib/http-conditional.php b/lib/http-conditional.php index 6d3a0a97f..ad920455d 100644 --- a/lib/http-conditional.php +++ b/lib/http-conditional.php @@ -93,12 +93,14 @@ function httpConditional($UnixTimeStamp,$cacheSeconds=0,$cachePrivacy=0,$feedMod } $etagServer='"'.md5($scriptName.$myQuery.'#'.$dateLastModif).'"'; + // @phpstan-ignore-next-line if ((!$is412)&&isset($_SERVER['HTTP_IF_MATCH'])) {//rfc2616-sec14.html#sec14.24 $etagsClient=stripslashes($_SERVER['HTTP_IF_MATCH']); $etagsClient=str_ireplace('-gzip','',$etagsClient); $is412=(($etagsClient!=='*')&&(strpos($etagsClient,$etagServer)===false)); } + // @phpstan-ignore-next-line if ($is304&&isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {//rfc2616-sec14.html#sec14.25 //rfc1945.txt $nbCond++; diff --git a/lib/lib_install.php b/lib/lib_install.php index 82c98d646..886fff54c 100644 --- a/lib/lib_install.php +++ b/lib/lib_install.php @@ -41,9 +41,13 @@ function checkRequirements($dbType = '') { $xml = function_exists('xml_parser_create'); $json = function_exists('json_encode'); $mbstring = extension_loaded('mbstring'); + // @phpstan-ignore-next-line $data = DATA_PATH && is_writable(DATA_PATH); + // @phpstan-ignore-next-line $cache = CACHE_PATH && is_writable(CACHE_PATH); + // @phpstan-ignore-next-line $tmp = TMP_PATH && is_writable(TMP_PATH); + // @phpstan-ignore-next-line $users = USERS_PATH && is_writable(USERS_PATH); $favicons = is_writable(join_path(DATA_PATH, 'favicons')); @@ -73,7 +77,7 @@ function checkRequirements($dbType = '') { } function generateSalt() { - return sha1(uniqid(mt_rand(), true).implode('', stat(__FILE__))); + return sha1(uniqid('' . mt_rand(), true).implode('', stat(__FILE__))); } function initDb() { diff --git a/lib/lib_phpQuery.php b/lib/lib_phpQuery.php index 797c1676a..29d06749c 100644 --- a/lib/lib_phpQuery.php +++ b/lib/lib_phpQuery.php @@ -4642,7 +4642,7 @@ abstract class phpQuery { * Creates new document from markup. * Chainable. * - * @param unknown_type $markup + * @param string $markup * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery */ public static function newDocument($markup = null, $contentType = null) { @@ -4655,7 +4655,7 @@ abstract class phpQuery { * Creates new document from markup. * Chainable. * - * @param unknown_type $markup + * @param string $markup * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery */ public static function newDocumentHTML($markup = null, $charset = null) { @@ -4668,7 +4668,7 @@ abstract class phpQuery { * Creates new document from markup. * Chainable. * - * @param unknown_type $markup + * @param string $markup * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery */ public static function newDocumentXML($markup = null, $charset = null) { @@ -4681,7 +4681,7 @@ abstract class phpQuery { * Creates new document from markup. * Chainable. * - * @param unknown_type $markup + * @param string $markup * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery */ public static function newDocumentXHTML($markup = null, $charset = null) { @@ -4694,7 +4694,7 @@ abstract class phpQuery { * Creates new document from markup. * Chainable. * - * @param unknown_type $markup + * @param string $markup * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery */ public static function newDocumentPHP($markup = null, $contentType = "text/html") { @@ -4784,7 +4784,7 @@ abstract class phpQuery { * Creates new document from markup. * Chainable. * - * @param unknown_type $markup + * @param string $markup * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery */ public static function newDocumentFileHTML($file, $charset = null) { @@ -4797,7 +4797,7 @@ abstract class phpQuery { * Creates new document from markup. * Chainable. * - * @param unknown_type $markup + * @param string $markup * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery */ public static function newDocumentFileXML($file, $charset = null) { @@ -4810,7 +4810,7 @@ abstract class phpQuery { * Creates new document from markup. * Chainable. * - * @param unknown_type $markup + * @param string $markup * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery */ public static function newDocumentFileXHTML($file, $charset = null) { @@ -4823,7 +4823,7 @@ abstract class phpQuery { * Creates new document from markup. * Chainable. * - * @param unknown_type $markup + * @param string $markup * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery */ public static function newDocumentFilePHP($file, $contentType = null) { diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 2627773b6..e347073a4 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -9,6 +9,7 @@ if (!function_exists('mb_strcut')) { } } +// @phpstan-ignore-next-line if (COPY_SYSLOG_TO_STDERR) { openlog('FreshRSS', LOG_CONS | LOG_ODELAY | LOG_PID | LOG_PERROR, LOG_USER); } else { @@ -18,7 +19,7 @@ if (COPY_SYSLOG_TO_STDERR) { /** * Build a directory path by concatenating a list of directory names. * - * @param array<string> $path_parts a list of directory names + * @param string $path_parts a list of directory names * @return string corresponding to the final pathname */ function join_path(...$path_parts) { @@ -52,6 +53,10 @@ function classAutoloader($class) { spl_autoload_register('classAutoloader'); //</Auto-loading> +/** + * @param string $url + * @return string + */ function idn_to_puny($url) { if (function_exists('idn_to_ascii')) { $idn = parse_url($url, PHP_URL_HOST); @@ -73,6 +78,11 @@ function idn_to_puny($url) { return $url; } +/** + * @param string $url + * @param bool $fixScheme + * @return string|false + */ function checkUrl($url, $fixScheme = true) { $url = trim($url); if ($url == '') { @@ -92,18 +102,39 @@ function checkUrl($url, $fixScheme = true) { } } +/** + * @param string $text + * @return string + */ function safe_ascii($text) { return filter_var($text, FILTER_DEFAULT, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH); } if (function_exists('mb_convert_encoding')) { + /** + * @param string $text + * @return string + */ function safe_utf8($text) { return mb_convert_encoding($text, 'UTF-8', 'UTF-8'); } } elseif (function_exists('iconv')) { + /** + * @param string $text + * @return string + */ function safe_utf8($text) { return iconv('UTF-8', 'UTF-8//IGNORE', $text); } } else { + /** + * @param string $text + * @return string + */ function safe_utf8($text) { return $text; } } +/** + * @param string $text + * @param bool $extended + * @return string + */ function escapeToUnicodeAlternative($text, $extended = true) { $text = htmlspecialchars_decode($text, ENT_QUOTES); @@ -156,6 +187,10 @@ function timestamptodate ($t, $hour = true) { return @date ($date, $t); } +/** + * @param string $text + * @return string + */ function html_only_entity_decode($text) { static $htmlEntitiesOnly = null; if ($htmlEntitiesOnly === null) { @@ -167,6 +202,10 @@ function html_only_entity_decode($text) { return $text == '' ? '' : strtr($text, $htmlEntitiesOnly); } +/** + * @param array<string,mixed> $attributes + * @return SimplePie + */ function customSimplePie($attributes = array()) { $limits = FreshRSS_Context::$system_conf->limits; $simplePie = new SimplePie(); @@ -276,7 +315,7 @@ function sanitizeHTML($data, $base = '', $maxLength = false) { */ function validateEmailAddress($email) { $mailer = new PHPMailer\PHPMailer\PHPMailer(); - $mailer->Charset = 'utf-8'; + $mailer->CharSet = 'utf-8'; $punyemail = $mailer->punyencodeAddress($email); return PHPMailer\PHPMailer\PHPMailer::validateAddress($punyemail, 'html5'); } @@ -294,9 +333,12 @@ function lazyimg($content) { ); } +/** + * @return string + */ function uTimeString() { $t = @gettimeofday(); - return $t['sec'] . str_pad($t['usec'], 6, '0', STR_PAD_LEFT); + return $t['sec'] . str_pad('' . $t['usec'], 6, '0', STR_PAD_LEFT); } function invalidateHttpCache($username = '') { @@ -311,6 +353,9 @@ function invalidateHttpCache($username = '') { return $ok; } +/** + * @return array<string> + */ function listUsers() { $final_list = array(); $base_path = join_path(DATA_PATH, 'users'); @@ -349,7 +394,7 @@ function max_registrations_reached() { * objects. If you need a long-time configuration, please don't use this function. * * @param string $username the name of the user of which we want the configuration. - * @return Minz_Configuration|null object, or null if the configuration cannot be loaded. + * @return FreshRSS_UserConfiguration|null object, or null if the configuration cannot be loaded. */ function get_user_configuration($username) { if (!FreshRSS_user_Controller::checkUsername($username)) { @@ -368,10 +413,16 @@ function get_user_configuration($username) { return null; } - return Minz_Configuration::get($namespace); + /** + * @var FreshRSS_UserConfiguration $user_conf + */ + $user_conf = Minz_Configuration::get($namespace); + return $user_conf; } - +/** + * @return string + */ function httpAuthUser() { if (!empty($_SERVER['REMOTE_USER'])) { return $_SERVER['REMOTE_USER']; @@ -383,6 +434,9 @@ function httpAuthUser() { return ''; } +/** + * @return bool + */ function cryptAvailable() { try { $hash = '$2y$04$usesomesillystringfore7hnbRJHxXVLeakoG8K30oukPsA.ztMG'; @@ -425,8 +479,11 @@ function check_install_php() { */ function check_install_files() { return array( + // @phpstan-ignore-next-line 'data' => DATA_PATH && is_writable(DATA_PATH), + // @phpstan-ignore-next-line 'cache' => CACHE_PATH && is_writable(CACHE_PATH), + // @phpstan-ignore-next-line 'users' => USERS_PATH && is_writable(USERS_PATH), 'favicons' => is_writable(DATA_PATH . '/favicons'), 'tokens' => is_writable(DATA_PATH . '/tokens'), @@ -497,8 +554,8 @@ function recursive_unlink($dir) { /** * Remove queries where $get is appearing. * @param string $get the get attribute which should be removed. - * @param array<string,string> $queries an array of queries. - * @return array<string,string> whithout queries where $get is appearing. + * @param array<int,array<string,string>> $queries an array of queries. + * @return array<int,array<string,string>> whithout queries where $get is appearing. */ function remove_query_by_get($get, $queries) { $final_queries = array(); diff --git a/p/api/fever.php b/p/api/fever.php index 684e851a6..6a7f10668 100644 --- a/p/api/fever.php +++ b/p/api/fever.php @@ -30,6 +30,9 @@ Minz_Session::init('FreshRSS', true); // <Debug> $ORIGINAL_INPUT = file_get_contents('php://input', false, null, 0, 1048576); +/** + * @return string + */ function debugInfo() { if (function_exists('getallheaders')) { $ALL_HEADERS = getallheaders(); @@ -503,18 +506,12 @@ class FeverAPI if (isset($_REQUEST['max_id'])) { // use the max_id argument to request the previous $item_limit items - $max_id = '' . $_REQUEST['max_id']; - if (!ctype_digit($max_id)) { - $max_id = null; - } + $max_id = ctype_digit('' . $_REQUEST['max_id']) ? intval($_REQUEST['max_id']) : null; } elseif (isset($_REQUEST['with_ids'])) { $entry_ids = explode(',', $_REQUEST['with_ids']); } elseif (isset($_REQUEST['since_id'])) { // use the since_id argument to request the next $item_limit items - $since_id = '' . $_REQUEST['since_id']; - if (!ctype_digit($since_id)) { - $since_id = null; - } + $since_id = ctype_digit('' . $_REQUEST['since_id']) ? intval($_REQUEST['since_id']) : null; } $items = array(); diff --git a/p/api/greader.php b/p/api/greader.php index 33373293d..d233fd957 100644 --- a/p/api/greader.php +++ b/p/api/greader.php @@ -29,20 +29,36 @@ require(LIB_PATH . '/lib_rss.php'); //Includes class autoloader $ORIGINAL_INPUT = file_get_contents('php://input', false, null, 0, 1048576); if (PHP_INT_SIZE < 8) { //32-bit + /** + * @param string|int $dec + * @return string + */ function dec2hex($dec) { return str_pad(gmp_strval(gmp_init($dec, 10), 16), 16, '0', STR_PAD_LEFT); } + /** + * @param string $hex + * @return string + */ function hex2dec($hex) { - if (!ctype_xdigit($hex)) return 0; + if (!ctype_xdigit($hex)) return '0'; return gmp_strval(gmp_init($hex, 16), 10); } } else { //64-bit + /** + * @param string|int $dec + * @return string + */ function dec2hex($dec) { //http://code.google.com/p/google-reader-api/wiki/ItemId return str_pad(dechex($dec), 16, '0', STR_PAD_LEFT); } + /** + * @param string $hex + * @return string + */ function hex2dec($hex) { - if (!ctype_xdigit($hex)) return 0; - return hexdec($hex); + if (!ctype_xdigit($hex)) return '0'; + return '' . hexdec($hex); } } @@ -79,6 +95,9 @@ function multiplePosts($name) { //https://bugs.php.net/bug.php?id=51633 return $result; } +/** + * @return string + */ function debugInfo() { if (function_exists('getallheaders')) { $ALL_HEADERS = getallheaders(); diff --git a/phpstan.neon b/phpstan.neon index 868dc93bd..63211cd68 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,6 +1,6 @@ parameters: # TODO: Increase rule-level https://phpstan.org/user-guide/rule-levels - level: 1 + level: 5 fileExtensions: - php - phtml |
