diff options
| author | 2023-04-17 08:30:21 +0200 | |
|---|---|---|
| committer | 2023-04-17 08:30:21 +0200 | |
| commit | f3760f138dcbaf7a2190336a0378cf1b2190c9f5 (patch) | |
| tree | 6fac8fbf9efd7aa74a8e3970ab70ccf85287b2cd /app | |
| parent | 41fa4e746df8c2e2399ed753b4994ca85cb21358 (diff) | |
Complete PHPStan Level 6 (#5305)
* Complete PHPStan Level 6
Fix https://github.com/FreshRSS/FreshRSS/issues/4112
And initiate PHPStan Level 7
* PHPStan Level 6 for tests
* Use phpstan/phpstan-phpunit
* Update to PHPStan version 1.10
* Fix mixed bug
* Fix mixed return bug
* Fix paginator bug
* Fix FreshRSS_UserConfiguration
* A couple more Minz_Configuration bug fixes
* A few trivial PHPStan Level 7 fixes
* A few more simple PHPStan Level 7
* More files passing PHPStan Level 7
Add interface to replace removed class from https://github.com/FreshRSS/FreshRSS/pull/5251
* A few more PHPStan Level 7 preparations
* A few last details
Diffstat (limited to 'app')
45 files changed, 273 insertions, 260 deletions
diff --git a/app/Controllers/categoryController.php b/app/Controllers/categoryController.php index 91cd92787..0ca1bbbcd 100644 --- a/app/Controllers/categoryController.php +++ b/app/Controllers/categoryController.php @@ -33,7 +33,7 @@ class FreshRSS_category_Controller extends FreshRSS_ActionController { $url_redirect = array('c' => 'subscription', 'a' => 'add'); $limits = FreshRSS_Context::$system_conf->limits; - $this->view->categories = $catDAO->listCategories(false); + $this->view->categories = $catDAO->listCategories(false) ?: []; if (count($this->view->categories) >= $limits['max_categories']) { Minz_Request::bad(_t('feedback.sub.category.over_max', $limits['max_categories']), $url_redirect); @@ -231,7 +231,7 @@ class FreshRSS_category_Controller extends FreshRSS_ActionController { if (Minz_Request::paramBoolean('ajax')) { Minz_Request::setGoodNotification(_t('feedback.sub.category.updated')); - $this->view->_layout(false); + $this->view->_layout(null); } else { if ($ok) { Minz_Request::good(_t('feedback.sub.category.updated'), $url_redirect); diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php index 667c2da74..87d9e4426 100644 --- a/app/Controllers/configureController.php +++ b/app/Controllers/configureController.php @@ -264,7 +264,7 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController { FreshRSS_Context::$user_conf->volatile = $volatile; $entryDAO = FreshRSS_Factory::createEntryDao(); - $this->view->nb_total = $entryDAO->count(); + $this->view->nb_total = $entryDAO->count() ?: 0; $databaseDAO = FreshRSS_Factory::createDatabaseDAO(); $this->view->size_user = $databaseDAO->size(); @@ -338,7 +338,7 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController { * applied to the selected query. */ public function queryAction(): void { - $this->view->_layout(false); + $this->view->_layout(null); $id = Minz_Request::paramInt('id'); if ($id !== 0 || !isset(FreshRSS_Context::$user_conf->queries[$id])) { diff --git a/app/Controllers/entryController.php b/app/Controllers/entryController.php index 7a30f94de..ff995b12f 100644 --- a/app/Controllers/entryController.php +++ b/app/Controllers/entryController.php @@ -24,7 +24,7 @@ class FreshRSS_entry_Controller extends FreshRSS_ActionController { // If ajax request, we do not print layout $this->ajax = Minz_Request::paramBoolean('ajax'); if ($this->ajax) { - $this->view->_layout(false); + $this->view->_layout(null); Minz_Request::_param('ajax'); } } @@ -107,7 +107,7 @@ class FreshRSS_entry_Controller extends FreshRSS_ActionController { $ids = is_array($id) ? $id : array($id); $entryDAO->markRead($ids, $is_read); $tagDAO = FreshRSS_Factory::createTagDao(); - $tagsForEntries = $tagDAO->getTagsForEntries($ids); + $tagsForEntries = $tagDAO->getTagsForEntries($ids) ?: []; $tags = array(); foreach ($tagsForEntries as $line) { $tags['t_' . $line['id_tag']][] = $line['id_entry']; diff --git a/app/Controllers/extensionController.php b/app/Controllers/extensionController.php index b482b1a35..4b440327d 100644 --- a/app/Controllers/extensionController.php +++ b/app/Controllers/extensionController.php @@ -79,7 +79,7 @@ class FreshRSS_extension_Controller extends FreshRSS_ActionController { */ public function configureAction(): void { if (Minz_Request::paramBoolean('ajax')) { - $this->view->_layout(false); + $this->view->_layout(null); } else { $this->indexAction(); $this->view->_path('extension/index.phtml'); @@ -143,7 +143,7 @@ class FreshRSS_extension_Controller extends FreshRSS_ActionController { if ($conf !== null && $res === true) { $ext_list = $conf->extensions_enabled; - $ext_list = array_filter($ext_list, function($key) use($type) { + $ext_list = array_filter($ext_list, static function(string $key) use($type) { // Remove from list the extensions that have disappeared or changed type $extension = Minz_ExtensionManager::findExtension($key); return $extension !== null && $extension->getType() === $type; @@ -205,7 +205,7 @@ class FreshRSS_extension_Controller extends FreshRSS_ActionController { if ($conf !== null && $res === true) { $ext_list = $conf->extensions_enabled; - $ext_list = array_filter($ext_list, function($key) use($type) { + $ext_list = array_filter($ext_list, static function(string $key) use($type) { // Remove from list the extensions that have disappeared or changed type $extension = Minz_ExtensionManager::findExtension($key); return $extension !== null && $extension->getType() === $type; diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index 39a1c7289..15bf0128b 100644 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -262,7 +262,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController { FreshRSS_View::prependTitle(_t('sub.feed.title_add') . ' · '); $catDAO = FreshRSS_Factory::createCategoryDao(); - $this->view->categories = $catDAO->listCategories(false); + $this->view->categories = $catDAO->listCategories(false) ?: []; $this->view->feed = new FreshRSS_Feed($url); try { // We try to get more information about the feed. @@ -316,7 +316,8 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController { /** * @return array{0:int,1:FreshRSS_Feed|false,2:int} */ - public static function actualizeFeed(int $feed_id, string $feed_url, bool $force, ?SimplePie $simplePiePush = null, bool $noCommit = false, int $maxFeeds = 10) { + public static function actualizeFeed(int $feed_id, string $feed_url, bool $force, ?SimplePie $simplePiePush = null, + bool $noCommit = false, int $maxFeeds = 10): array { @set_time_limit(300); $feedDAO = FreshRSS_Factory::createFeedDao(); @@ -666,7 +667,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController { // are several updated feeds. Minz_Request::setGoodNotification(_t('feedback.sub.feed.actualizeds')); // No layout in ajax request. - $this->view->_layout(false); + $this->view->_layout(null); } else { // Redirect to the main page with correct notification. if ($updated_feeds === 1) { @@ -903,7 +904,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController { $this->view->selectorSuccess = false; $this->view->htmlContent = ''; - $this->view->_layout(false); + $this->view->_layout(null); $this->_csp([ 'default-src' => "'self'", diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 2df185398..4939a0748 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -226,7 +226,7 @@ class FreshRSS_importExport_Controller extends FreshRSS_ActionController { unset($table['article']); for ($i = count($table['items']) - 1; $i >= 0; $i--) { $item = (array)($table['items'][$i]); - $item = array_filter($item, function ($v) { + $item = array_filter($item, static function ($v) { // Filter out empty properties, potentially reported as empty objects return (is_string($v) && trim($v) !== '') || !empty($v); }); @@ -267,7 +267,7 @@ class FreshRSS_importExport_Controller extends FreshRSS_ActionController { * * $article_file the JSON file content. * true if articles from the file must be starred. - * @return boolean false if an error occurred, true otherwise. + * @return bool false if an error occurred, true otherwise. */ private function importJson(string $article_file, bool $starred = false): bool { $article_object = json_decode($article_file, true); @@ -575,10 +575,8 @@ class FreshRSS_importExport_Controller extends FreshRSS_ActionController { * - export_starred (default: false) * - export_labelled (default: false) * - export_feeds (default: array()) a list of feed ids - * - * @return void|null */ - public function exportAction() { + public function exportAction(): void { if (!Minz_Request::isPost()) { Minz_Request::forward(['c' => 'importExport', 'a' => 'index'], true); return; @@ -654,7 +652,7 @@ class FreshRSS_importExport_Controller extends FreshRSS_ActionController { header('Content-Type: ' . $content_type); header('Content-disposition: attachment; filename="' . $filename . '"'); - $this->view->_layout(false); + $this->view->_layout(null); $this->view->content = $content; } diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index 17aee3585..64371c530 100644 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -58,10 +58,10 @@ class FreshRSS_index_Controller extends FreshRSS_ActionController { FreshRSS_Context::$id_max = time() . '000000'; - $this->view->callbackBeforeFeeds = function ($view) { + $this->view->callbackBeforeFeeds = function (FreshRSS_View $view) { try { $tagDAO = FreshRSS_Factory::createTagDao(); - $view->tags = $tagDAO->listTags(true); + $view->tags = $tagDAO->listTags(true) ?: []; $view->nbUnreadTags = 0; foreach ($view->tags as $tag) { $view->nbUnreadTags += $tag->nbUnread(); @@ -71,7 +71,7 @@ class FreshRSS_index_Controller extends FreshRSS_ActionController { } }; - $this->view->callbackBeforeEntries = function ($view) { + $this->view->callbackBeforeEntries = function (FreshRSS_View $view) { try { FreshRSS_Context::$number++; //+1 for articles' page $view->entries = FreshRSS_index_Controller::listEntriesByContext(); @@ -83,7 +83,7 @@ class FreshRSS_index_Controller extends FreshRSS_ActionController { } }; - $this->view->callbackBeforePagination = function ($view, $nbEntries, $lastEntry) { + $this->view->callbackBeforePagination = function (?FreshRSS_View $view, int $nbEntries, FreshRSS_Entry $lastEntry) { if ($nbEntries >= FreshRSS_Context::$number) { //We have enough entries: we discard the last one to use it for the next articles' page ob_clean(); @@ -170,7 +170,7 @@ class FreshRSS_index_Controller extends FreshRSS_ActionController { // No layout for RSS output. $this->view->rss_url = PUBLIC_TO_INDEX_PATH . '/' . (empty($_SERVER['QUERY_STRING']) ? '' : '?' . $_SERVER['QUERY_STRING']); $this->view->rss_title = FreshRSS_Context::$name . ' | ' . FreshRSS_View::title(); - $this->view->_layout(false); + $this->view->_layout(null); header('Content-Type: application/rss+xml; charset=utf-8'); } @@ -238,7 +238,7 @@ class FreshRSS_index_Controller extends FreshRSS_ActionController { } // No layout for OPML output. - $this->view->_layout(false); + $this->view->_layout(null); header('Content-Type: application/xml; charset=utf-8'); } diff --git a/app/Controllers/javascriptController.php b/app/Controllers/javascriptController.php index d7c600113..ce25d03c9 100644 --- a/app/Controllers/javascriptController.php +++ b/app/Controllers/javascriptController.php @@ -3,7 +3,7 @@ class FreshRSS_javascript_Controller extends FreshRSS_ActionController { public function firstAction(): void { - $this->view->_layout(false); + $this->view->_layout(null); } public function actualizeAction(): void { @@ -20,9 +20,9 @@ class FreshRSS_javascript_Controller extends FreshRSS_ActionController { public function nbUnreadsPerFeedAction(): void { header('Content-Type: application/json; charset=UTF-8'); $catDAO = FreshRSS_Factory::createCategoryDao(); - $this->view->categories = $catDAO->listCategories(true, false); + $this->view->categories = $catDAO->listCategories(true, false) ?: []; $tagDAO = FreshRSS_Factory::createTagDao(); - $this->view->tags = $tagDAO->listTags(true); + $this->view->tags = $tagDAO->listTags(true) ?: []; } //For Web-form login diff --git a/app/Controllers/statsController.php b/app/Controllers/statsController.php index cd9a247c4..0fc6490f8 100644 --- a/app/Controllers/statsController.php +++ b/app/Controllers/statsController.php @@ -26,7 +26,7 @@ class FreshRSS_stats_Controller extends FreshRSS_ActionController { $catDAO->checkDefault(); $feedDAO->updateTTL(); - $this->view->categories = $catDAO->listSortedCategories(false); + $this->view->categories = $catDAO->listSortedCategories(false) ?: []; $this->view->default_category = $catDAO->getDefault(); FreshRSS_View::prependTitle(_t('admin.stats.title') . ' · '); @@ -207,7 +207,7 @@ class FreshRSS_stats_Controller extends FreshRSS_ActionController { $id = null; } - $this->view->categories = $categoryDAO->listCategories(); + $this->view->categories = $categoryDAO->listCategories() ?: []; $this->view->feed = $id === null ? null : $feedDAO->searchById($id); $this->view->days = $statsDAO->getDays(); $this->view->months = $statsDAO->getMonths(); diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php index e0a8d4ff4..d96cb02e1 100644 --- a/app/Controllers/subscriptionController.php +++ b/app/Controllers/subscriptionController.php @@ -19,7 +19,7 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController { $catDAO->checkDefault(); $feedDAO->updateTTL(); - $this->view->categories = $catDAO->listSortedCategories(false, true); + $this->view->categories = $catDAO->listSortedCategories(false, true) ?: []; $this->view->default_category = $catDAO->getDefault(); $signalError = false; @@ -90,7 +90,7 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController { */ public function feedAction(): void { if (Minz_Request::paramBoolean('ajax')) { - $this->view->_layout(false); + $this->view->_layout(null); } else { FreshRSS_View::appendScript(Minz_Url::display('/scripts/feed.js?' . @filemtime(PUBLIC_PATH . '/scripts/feed.js'))); } @@ -200,7 +200,7 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController { ]); } - $feed->_filtersAction('read', preg_split('/[\n\r]+/', Minz_Request::paramString('filteractions_read'))); + $feed->_filtersAction('read', preg_split('/[\n\r]+/', Minz_Request::paramString('filteractions_read')) ?: []); $feed->_kind(Minz_Request::paramInt('feed_kind') ?: FreshRSS_Feed::KIND_RSS); if ($feed->kind() === FreshRSS_Feed::KIND_HTML_XPATH || $feed->kind() === FreshRSS_Feed::KIND_XML_XPATH) { @@ -235,8 +235,8 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController { 'name' => Minz_Request::paramString('name'), 'kind' => $feed->kind(), 'description' => sanitizeHTML(Minz_Request::paramString('description', true)), - 'website' => checkUrl(Minz_Request::paramString('website')), - 'url' => checkUrl(Minz_Request::paramString('url')), + 'website' => checkUrl(Minz_Request::paramString('website')) ?: '', + 'url' => checkUrl(Minz_Request::paramString('url')) ?: '', 'category' => Minz_Request::paramInt('category'), 'pathEntries' => Minz_Request::paramString('path_entries'), 'priority' => Minz_Request::paramTernary('priority') === null ? FreshRSS_Feed::PRIORITY_MAIN_STREAM : Minz_Request::paramInt('priority'), @@ -283,7 +283,7 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController { } public function categoryAction(): void { - $this->view->_layout(false); + $this->view->_layout(null); $categoryDAO = FreshRSS_Factory::createCategoryDao(); diff --git a/app/Controllers/tagController.php b/app/Controllers/tagController.php index e4048238c..7a89b2b84 100644 --- a/app/Controllers/tagController.php +++ b/app/Controllers/tagController.php @@ -23,7 +23,7 @@ class FreshRSS_tag_Controller extends FreshRSS_ActionController { // If ajax request, we do not print layout $this->ajax = Minz_Request::paramBoolean('ajax'); if ($this->ajax) { - $this->view->_layout(false); + $this->view->_layout(null); Minz_Request::_param('ajax'); } } @@ -39,7 +39,7 @@ class FreshRSS_tag_Controller extends FreshRSS_ActionController { $checked = Minz_Request::paramTernary('checked'); if ($id_entry != '') { $tagDAO = FreshRSS_Factory::createTagDao(); - if ($id_tag === 0 && $name_tag !== '' && $checked) { + if ($id_tag == 0 && $name_tag !== '' && $checked) { if ($existing_tag = $tagDAO->searchByName($name_tag)) { // Use existing tag $tagDAO->tagEntry($existing_tag->id(), $id_entry, $checked); @@ -48,7 +48,7 @@ class FreshRSS_tag_Controller extends FreshRSS_ActionController { $id_tag = $tagDAO->addTag(array('name' => $name_tag)); } } - if ($id_tag !== 0) { + if ($id_tag != false) { $tagDAO->tagEntry($id_tag, $id_entry, $checked); } } @@ -82,12 +82,12 @@ class FreshRSS_tag_Controller extends FreshRSS_ActionController { } public function getTagsForEntryAction(): void { - $this->view->_layout(false); + $this->view->_layout(null); header('Content-Type: application/json; charset=UTF-8'); header('Cache-Control: private, no-cache, no-store, must-revalidate'); $id_entry = Minz_Request::paramString('id_entry'); $tagDAO = FreshRSS_Factory::createTagDao(); - $this->view->tagsForEntry = $tagDAO->getTagsForEntry($id_entry); + $this->view->tagsForEntry = $tagDAO->getTagsForEntry($id_entry) ?: []; } public function addAction(): void { @@ -110,11 +110,10 @@ class FreshRSS_tag_Controller extends FreshRSS_ActionController { } /** - * @return void|null * @throws Minz_ConfigurationNamespaceException * @throws Minz_PDOConnectionException */ - public function renameAction() { + public function renameAction(): void { if (!Minz_Request::isPost()) { Minz_Error::error(405); } @@ -145,6 +144,6 @@ class FreshRSS_tag_Controller extends FreshRSS_ActionController { public function indexAction(): void { $tagDAO = FreshRSS_Factory::createTagDao(); - $this->view->tags = $tagDAO->listTags(); + $this->view->tags = $tagDAO->listTags() ?: []; } } diff --git a/app/Models/Auth.php b/app/Models/Auth.php index 8fd06b24d..e868e1b4f 100644 --- a/app/Models/Auth.php +++ b/app/Models/Auth.php @@ -135,9 +135,9 @@ class FreshRSS_Auth { * Returns if current user has access to the given scope. * * @param string $scope general (default) or admin - * @return boolean true if user has corresponding access, false else. + * @return bool true if user has corresponding access, false else. */ - public static function hasAccess($scope = 'general'): bool { + public static function hasAccess(string $scope = 'general'): bool { if (FreshRSS_Context::$user_conf == null) { return false; } @@ -154,7 +154,7 @@ class FreshRSS_Auth { default: $ok = false; } - return $ok; + return (bool)$ok; } /** diff --git a/app/Models/BooleanSearch.php b/app/Models/BooleanSearch.php index 89e6e3ee2..f4979b22b 100644 --- a/app/Models/BooleanSearch.php +++ b/app/Models/BooleanSearch.php @@ -230,7 +230,7 @@ class FreshRSS_BooleanSearch { if ($input == '') { return; } - $splits = preg_split('/\b(OR)\b/i', $input, -1, PREG_SPLIT_DELIM_CAPTURE); + $splits = preg_split('/\b(OR)\b/i', $input, -1, PREG_SPLIT_DELIM_CAPTURE) ?: []; $segment = ''; $ns = count($splits); diff --git a/app/Models/Category.php b/app/Models/Category.php index 737544481..4e28b1741 100644 --- a/app/Models/Category.php +++ b/app/Models/Category.php @@ -262,7 +262,7 @@ class FreshRSS_Category extends Minz_Model { $catDAO = FreshRSS_Factory::createCategoryDao(); $catDAO->updateLastUpdate($this->id(), !$ok); - return $ok; + return (bool)$ok; } private function sortFeeds(): void { diff --git a/app/Models/CategoryDAO.php b/app/Models/CategoryDAO.php index 64b14ffb7..29593ce5f 100644 --- a/app/Models/CategoryDAO.php +++ b/app/Models/CategoryDAO.php @@ -477,7 +477,7 @@ SQL; $cat->_id($previousLine['c_id']); $cat->_kind($previousLine['c_kind']); $cat->_lastUpdate($previousLine['c_last_update'] ?? 0); - $cat->_error($previousLine['c_error'] ?? false); + $cat->_error($previousLine['c_error'] ?? 0); $cat->_attributes('', $previousLine['c_attributes']); $list[$previousLine['c_id']] = $cat; } diff --git a/app/Models/Context.php b/app/Models/Context.php index b2631291a..03006cbbf 100644 --- a/app/Models/Context.php +++ b/app/Models/Context.php @@ -110,10 +110,9 @@ final class FreshRSS_Context { /** * Initialize the context for the current user. - * @return FreshRSS_UserConfiguration|false * @throws Minz_ConfigurationParamException */ - public static function initUser(string $username = '', bool $userMustExist = true) { + public static function initUser(string $username = '', bool $userMustExist = true): ?FreshRSS_UserConfiguration { FreshRSS_Context::$user_conf = null; if (!isset($_SESSION)) { Minz_Session::init('FreshRSS'); @@ -145,7 +144,7 @@ final class FreshRSS_Context { Minz_Session::unlock(); if (FreshRSS_Context::$user_conf == null) { - return false; + return null; } FreshRSS_Context::$search = new FreshRSS_BooleanSearch(''); @@ -249,8 +248,8 @@ final class FreshRSS_Context { /** * Return the current get as a string or an array. * - * If $array is true, the first item of the returned value is 'f' or 'c' and - * the second is the id. + * If $array is true, the first item of the returned value is 'f' or 'c' or 't' and the second is the id. + * @phpstan-return ($asArray is true ? array{'c'|'f'|'t',bool|int} : string) * @return string|array{string,bool|int} */ public static function currentGet(bool $asArray = false) { diff --git a/app/Models/DatabaseDAO.php b/app/Models/DatabaseDAO.php index 28dd36cd9..aeac6f435 100644 --- a/app/Models/DatabaseDAO.php +++ b/app/Models/DatabaseDAO.php @@ -79,7 +79,7 @@ class FreshRSS_DatabaseDAO extends Minz_ModelPdo { $ok &= in_array($c['name'], $schema); } - return $ok; + return (bool)$ok; } public function categoryIsCorrect(): bool { diff --git a/app/Models/DatabaseDAOSQLite.php b/app/Models/DatabaseDAOSQLite.php index 3fab1134d..0909613a7 100644 --- a/app/Models/DatabaseDAOSQLite.php +++ b/app/Models/DatabaseDAOSQLite.php @@ -8,7 +8,10 @@ class FreshRSS_DatabaseDAOSQLite extends FreshRSS_DatabaseDAO { public function tablesAreCorrect(): bool { $sql = 'SELECT name FROM sqlite_master WHERE type="table"'; $stm = $this->pdo->query($sql); - $res = $stm->fetchAll(PDO::FETCH_ASSOC); + $res = $stm ? $stm->fetchAll(PDO::FETCH_ASSOC) : false; + if ($res === false) { + return false; + } $tables = array( $this->pdo->prefix() . 'category' => false, @@ -29,7 +32,7 @@ class FreshRSS_DatabaseDAOSQLite extends FreshRSS_DatabaseDAO { public function getSchema(string $table): array { $sql = 'PRAGMA table_info(' . $table . ')'; $stm = $this->pdo->query($sql); - return $this->listDaoToSchema($stm->fetchAll(PDO::FETCH_ASSOC)); + return $stm ? $this->listDaoToSchema($stm->fetchAll(PDO::FETCH_ASSOC) ?: []) : []; } public function entryIsCorrect(): bool { @@ -62,7 +65,7 @@ class FreshRSS_DatabaseDAOSQLite extends FreshRSS_DatabaseDAO { public function size(bool $all = false): int { $sum = 0; if ($all) { - foreach (glob(DATA_PATH . '/users/*/db.sqlite') as $filename) { + foreach (glob(DATA_PATH . '/users/*/db.sqlite') ?: [] as $filename) { $sum += @filesize($filename); } } else { diff --git a/app/Models/Entry.php b/app/Models/Entry.php index d208b07ec..20f17d1c7 100644 --- a/app/Models/Entry.php +++ b/app/Models/Entry.php @@ -106,7 +106,7 @@ class FreshRSS_Entry extends Minz_Model { return $this->authors(true); } /** - * @phpstan return ($asString ? string : array<string>) + * @phpstan-return ($asString is true ? string : array<string>) * @return string|array<string> */ public function authors(bool $asString = false) { @@ -285,7 +285,7 @@ HTML; /** * @return array<string,string>|null */ - public function thumbnail(bool $searchEnclosures = true) { + public function thumbnail(bool $searchEnclosures = true): ?array { $thumbnail = $this->attributes('thumbnail'); if (!empty($thumbnail['url'])) { return $thumbnail; @@ -352,7 +352,10 @@ HTML; return $this->feedId; } - /** @return string|array<string> */ + /** + * @phpstan-return ($asString is true ? string : array<string>) + * @return string|array<string> + */ public function tags(bool $asString = false) { if ($asString) { return $this->tags == null ? '' : '#' . implode(' #', $this->tags); @@ -609,7 +612,7 @@ HTML; } } } - return $ok; + return (bool)$ok; } /** @param array<string,int> $titlesAsRead */ diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index 9f24beb7c..1661bfd13 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -308,7 +308,7 @@ SQL; * there is an other way to do that. * * @param string|array<string> $ids - * @return false|integer + * @return int|false */ public function markFavorite($ids, bool $is_favorite = true) { if (!is_array($ids)) { @@ -348,12 +348,8 @@ SQL; * feeds from one category or on all feeds. * * @todo It can use the query builder refactoring to build that query - * - * @param false|integer $catId category ID - * @param false|integer $feedId feed ID - * @return boolean */ - protected function updateCacheUnreads($catId = false, $feedId = false) { + protected function updateCacheUnreads(?int $catId = null, ?int $feedId = null): bool { $sql = 'UPDATE `_feed` f ' . 'LEFT OUTER JOIN (' . 'SELECT e.id_feed, ' @@ -365,13 +361,13 @@ SQL; . 'SET f.`cache_nbUnreads`=COALESCE(x.nbUnreads, 0)'; $hasWhere = false; $values = array(); - if ($feedId !== false) { + if ($feedId != null) { $sql .= ' WHERE'; $hasWhere = true; $sql .= ' f.id=?'; $values[] = $feedId; } - if ($catId !== false) { + if ($catId != null) { $sql .= $hasWhere ? ' AND' : ' WHERE'; $hasWhere = true; $sql .= ' f.category=?'; @@ -397,8 +393,8 @@ SQL; * same if it is an array or not. * * @param string|array<string> $ids - * @param boolean $is_read - * @return integer|false affected rows + * @param bool $is_read + * @return int|false affected rows */ public function markRead($ids, bool $is_read = true) { FreshRSS_UserDAO::touch(); @@ -431,7 +427,7 @@ SQL; return false; } $affected = $stm->rowCount(); - if (($affected > 0) && (!$this->updateCacheUnreads(false, false))) { + if (($affected > 0) && (!$this->updateCacheUnreads(null, null))) { return false; } return $affected; @@ -469,7 +465,7 @@ SQL; * separated. * * @param string $idMax fail safe article ID - * @return integer|false affected rows + * @return int|false affected rows */ public function markReadEntries(string $idMax = '0', bool $onlyFavorites = false, int $priorityMin = 0, ?FreshRSS_BooleanSearch $filters = null, int $state = 0, bool $is_read = true) { @@ -498,7 +494,7 @@ SQL; return false; } $affected = $stm->rowCount(); - if (($affected > 0) && (!$this->updateCacheUnreads(false, false))) { + if (($affected > 0) && (!$this->updateCacheUnreads(null, null))) { return false; } return $affected; @@ -511,9 +507,9 @@ SQL; * * If $idMax equals 0, a deprecated debug message is logged * - * @param integer $id category ID + * @param int $id category ID * @param string $idMax fail safe article ID - * @return integer|false affected rows + * @return int|false affected rows */ public function markReadCat(int $id, string $idMax = '0', ?FreshRSS_BooleanSearch $filters = null, int $state = 0, bool $is_read = true) { FreshRSS_UserDAO::touch(); @@ -536,7 +532,7 @@ SQL; return false; } $affected = $stm->rowCount(); - if (($affected > 0) && (!$this->updateCacheUnreads($id, false))) { + if (($affected > 0) && (!$this->updateCacheUnreads($id, null))) { return false; } return $affected; @@ -549,9 +545,9 @@ SQL; * * If $idMax equals 0, a deprecated debug message is logged * - * @param integer $id_feed feed ID + * @param int $id_feed feed ID * @param string $idMax fail safe article ID - * @return integer|false affected rows + * @return int|false affected rows */ public function markReadFeed(int $id_feed, string $idMax = '0', ?FreshRSS_BooleanSearch $filters = null, int $state = 0, bool $is_read = true) { FreshRSS_UserDAO::touch(); @@ -597,9 +593,9 @@ SQL; /** * Mark all the articles in a tag as read. - * @param integer $id tag ID, or empty for targeting any tag + * @param int $id tag ID, or empty for targeting any tag * @param string $idMax max article ID - * @return integer|false affected rows + * @return int|false affected rows */ public function markReadTag(int $id = 0, string $idMax = '0', ?FreshRSS_BooleanSearch $filters = null, int $state = 0, bool $is_read = true) { @@ -630,7 +626,7 @@ SQL; return false; } $affected = $stm->rowCount(); - if (($affected > 0) && (!$this->updateCacheUnreads(false, false))) { + if (($affected > 0) && (!$this->updateCacheUnreads(null, null))) { return false; } return $affected; @@ -758,7 +754,7 @@ SQL; } /** @return array{0:array<int|string>,1:string} */ - public static function sqlBooleanSearch(string $alias, FreshRSS_BooleanSearch $filters, int $level = 0) { + public static function sqlBooleanSearch(string $alias, FreshRSS_BooleanSearch $filters, int $level = 0): array { $search = ''; $values = []; diff --git a/app/Models/EntryDAOSQLite.php b/app/Models/EntryDAOSQLite.php index e509097f2..c86791372 100644 --- a/app/Models/EntryDAOSQLite.php +++ b/app/Models/EntryDAOSQLite.php @@ -25,7 +25,7 @@ class FreshRSS_EntryDAOSQLite extends FreshRSS_EntryDAO { /** @param array<string> $errorInfo */ protected function autoUpdateDb(array $errorInfo): bool { if ($tableInfo = $this->pdo->query("PRAGMA table_info('entry')")) { - $columns = $tableInfo->fetchAll(PDO::FETCH_COLUMN, 1); + $columns = $tableInfo->fetchAll(PDO::FETCH_COLUMN, 1) ?: []; foreach (['attributes'] as $column) { if (!in_array($column, $columns)) { return $this->addColumn($column); @@ -34,14 +34,14 @@ class FreshRSS_EntryDAOSQLite extends FreshRSS_EntryDAO { } if ($tableInfo = $this->pdo->query("SELECT sql FROM sqlite_master where name='tag'")) { $showCreate = $tableInfo->fetchColumn(); - if (stripos($showCreate, 'tag') === false) { + if (is_string($showCreate) && stripos($showCreate, 'tag') === false) { $tagDAO = FreshRSS_Factory::createTagDao(); return $tagDAO->createTagTable(); //v1.12.0 } } if ($tableInfo = $this->pdo->query("SELECT sql FROM sqlite_master where name='entrytmp'")) { $showCreate = $tableInfo->fetchColumn(); - if (stripos($showCreate, 'entrytmp') === false) { + if (is_string($showCreate) && stripos($showCreate, 'entrytmp') === false) { return $this->createEntryTempTable(); //v1.7.0 } } @@ -78,20 +78,20 @@ DROP TABLE IF EXISTS `tmp`; return $result; } - protected function updateCacheUnreads($catId = false, $feedId = false) { + protected function updateCacheUnreads(?int $catId = null, ?int $feedId = null): bool { $sql = 'UPDATE `_feed` ' . 'SET `cache_nbUnreads`=(' . 'SELECT COUNT(*) AS nbUnreads FROM `_entry` e ' . 'WHERE e.id_feed=`_feed`.id AND e.is_read=0)'; $hasWhere = false; $values = array(); - if ($feedId !== false) { + if ($feedId != null) { $sql .= ' WHERE'; $hasWhere = true; $sql .= ' id=?'; $values[] = $feedId; } - if ($catId !== false) { + if ($catId != null) { $sql .= $hasWhere ? ' AND' : ' WHERE'; $hasWhere = true; $sql .= ' category=?'; @@ -117,8 +117,8 @@ DROP TABLE IF EXISTS `tmp`; * same if it is an array or not. * * @param string|array<string> $ids - * @param boolean $is_read - * @return integer|false affected rows + * @param bool $is_read + * @return int|false affected rows */ public function markRead($ids, bool $is_read = true) { FreshRSS_UserDAO::touch(); @@ -176,9 +176,9 @@ DROP TABLE IF EXISTS `tmp`; * separated. * * @param string $idMax fail safe article ID - * @param boolean $onlyFavorites - * @param integer $priorityMin - * @return integer|false affected rows + * @param bool $onlyFavorites + * @param int $priorityMin + * @return int|false affected rows */ public function markReadEntries(string $idMax = '0', bool $onlyFavorites = false, int $priorityMin = 0, ?FreshRSS_BooleanSearch $filters = null, int $state = 0, bool $is_read = true) { @@ -205,7 +205,7 @@ DROP TABLE IF EXISTS `tmp`; return false; } $affected = $stm->rowCount(); - if (($affected > 0) && (!$this->updateCacheUnreads(false, false))) { + if (($affected > 0) && (!$this->updateCacheUnreads(null, null))) { return false; } return $affected; @@ -218,9 +218,9 @@ DROP TABLE IF EXISTS `tmp`; * * If $idMax equals 0, a deprecated debug message is logged * - * @param integer $id category ID + * @param int $id category ID * @param string $idMax fail safe article ID - * @return integer|false affected rows + * @return int|false affected rows */ public function markReadCat(int $id, string $idMax = '0', ?FreshRSS_BooleanSearch $filters = null, int $state = 0, bool $is_read = true) { FreshRSS_UserDAO::touch(); @@ -244,7 +244,7 @@ DROP TABLE IF EXISTS `tmp`; return false; } $affected = $stm->rowCount(); - if (($affected > 0) && (!$this->updateCacheUnreads($id, false))) { + if (($affected > 0) && (!$this->updateCacheUnreads($id, null))) { return false; } return $affected; @@ -252,9 +252,9 @@ DROP TABLE IF EXISTS `tmp`; /** * Mark all the articles in a tag as read. - * @param integer $id tag ID, or empty for targeting any tag + * @param int $id tag ID, or empty for targeting any tag * @param string $idMax max article ID - * @return integer|false affected rows + * @return int|false affected rows */ public function markReadTag($id = 0, string $idMax = '0', ?FreshRSS_BooleanSearch $filters = null, int $state = 0, bool $is_read = true) { FreshRSS_UserDAO::touch(); @@ -283,7 +283,7 @@ DROP TABLE IF EXISTS `tmp`; return false; } $affected = $stm->rowCount(); - if (($affected > 0) && (!$this->updateCacheUnreads(false, false))) { + if (($affected > 0) && (!$this->updateCacheUnreads(null, null))) { return false; } return $affected; diff --git a/app/Models/Factory.php b/app/Models/Factory.php index 80c611db5..d06c3c63d 100644 --- a/app/Models/Factory.php +++ b/app/Models/Factory.php @@ -13,7 +13,7 @@ class FreshRSS_Factory { * @throws Minz_ConfigurationNamespaceException|Minz_PDOConnectionException */ public static function createCategoryDao(?string $username = null): FreshRSS_CategoryDAO { - switch (FreshRSS_Context::$system_conf->db['type']) { + switch (FreshRSS_Context::$system_conf->db['type'] ?? '') { case 'sqlite': return new FreshRSS_CategoryDAOSQLite($username); default: @@ -25,7 +25,7 @@ class FreshRSS_Factory { * @throws Minz_ConfigurationNamespaceException|Minz_PDOConnectionException */ public static function createFeedDao(?string $username = null): FreshRSS_FeedDAO { - switch (FreshRSS_Context::$system_conf->db['type']) { + switch (FreshRSS_Context::$system_conf->db['type'] ?? '') { case 'sqlite': return new FreshRSS_FeedDAOSQLite($username); default: @@ -37,7 +37,7 @@ class FreshRSS_Factory { * @throws Minz_ConfigurationNamespaceException|Minz_PDOConnectionException */ public static function createEntryDao(?string $username = null): FreshRSS_EntryDAO { - switch (FreshRSS_Context::$system_conf->db['type']) { + switch (FreshRSS_Context::$system_conf->db['type'] ?? '') { case 'sqlite': return new FreshRSS_EntryDAOSQLite($username); case 'pgsql': @@ -51,7 +51,7 @@ class FreshRSS_Factory { * @throws Minz_ConfigurationNamespaceException|Minz_PDOConnectionException */ public static function createTagDao(?string $username = null): FreshRSS_TagDAO { - switch (FreshRSS_Context::$system_conf->db['type']) { + switch (FreshRSS_Context::$system_conf->db['type'] ?? '') { case 'sqlite': return new FreshRSS_TagDAOSQLite($username); case 'pgsql': @@ -65,7 +65,7 @@ class FreshRSS_Factory { * @throws Minz_ConfigurationNamespaceException|Minz_PDOConnectionException */ public static function createStatsDAO(?string $username = null): FreshRSS_StatsDAO { - switch (FreshRSS_Context::$system_conf->db['type']) { + switch (FreshRSS_Context::$system_conf->db['type'] ?? '') { case 'sqlite': return new FreshRSS_StatsDAOSQLite($username); case 'pgsql': @@ -79,7 +79,7 @@ class FreshRSS_Factory { * @throws Minz_ConfigurationNamespaceException|Minz_PDOConnectionException */ public static function createDatabaseDAO(?string $username = null): FreshRSS_DatabaseDAO { - switch (FreshRSS_Context::$system_conf->db['type']) { + switch (FreshRSS_Context::$system_conf->db['type'] ?? '') { case 'sqlite': return new FreshRSS_DatabaseDAOSQLite($username); case 'pgsql': diff --git a/app/Models/Feed.php b/app/Models/Feed.php index 447445d46..ecf875723 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -71,6 +71,7 @@ class FreshRSS_Feed extends Minz_Model { private $error = false; /** @var int */ private $ttl = self::TTL_DEFAULT; + /** @var array<string,mixed> */ private $attributes = []; /** @var bool */ private $mute = false; @@ -93,10 +94,7 @@ class FreshRSS_Feed extends Minz_Model { } } - /** - * @return FreshRSS_Feed - */ - public static function example() { + public static function example(): FreshRSS_Feed { $f = new FreshRSS_Feed('http://example.net/', false); $f->faviconPrepare(); return $f; @@ -142,12 +140,16 @@ class FreshRSS_Feed extends Minz_Model { return $this->categoryId; } - public function entries() { + /** + * @return array<FreshRSS_Entry>|null + * @deprecated + */ + public function entries(): ?array { Minz_Log::warning(__method__ . ' is deprecated since FreshRSS 1.16.1!'); $simplePie = $this->load(false, true); return $simplePie == null ? [] : iterator_to_array($this->loadEntries($simplePie)); } - public function name($raw = false): string { + public function name(bool $raw = false): string { return $raw || $this->name != '' ? $this->name : preg_replace('%^https?://(www[.])?%i', '', $this->url); } /** @return string HTML-encoded URL of the Web site of the feed */ @@ -167,7 +169,11 @@ class FreshRSS_Feed extends Minz_Model { public function pathEntries(): string { return $this->pathEntries; } - public function httpAuth($raw = true) { + /** + * @phpstan-return ($raw is true ? string : array{'username':string,'password':string}) + * @return array{'username':string,'password':string}|string + */ + public function httpAuth(bool $raw = true) { if ($raw) { return $this->httpAuth; } else { @@ -223,7 +229,7 @@ class FreshRSS_Feed extends Minz_Model { return $this->nbEntries; } - public function nbNotRead($includePending = false): int { + public function nbNotRead(bool $includePending = false): int { if ($this->nbNotRead < 0) { $feedDAO = FreshRSS_Factory::createFeedDao(); $this->nbNotRead = $feedDAO->countNotRead($this->id()); @@ -231,7 +237,7 @@ class FreshRSS_Feed extends Minz_Model { return $this->nbNotRead + ($includePending ? $this->nbPendingNotRead : 0); } - public function faviconPrepare() { + public function faviconPrepare(): void { require_once(LIB_PATH . '/favicons.php'); $url = $this->website; if ($url == '') { @@ -253,7 +259,7 @@ class FreshRSS_Feed extends Minz_Model { } } } - public static function faviconDelete($hash) { + public static function faviconDelete(string $hash): void { $path = DATA_PATH . '/favicons/' . $hash; @unlink($path . '.ico'); @unlink($path . '.txt'); @@ -262,10 +268,11 @@ class FreshRSS_Feed extends Minz_Model { return Minz_Url::display('/f.php?' . $this->hash()); } - public function _id($value) { - $this->id = intval($value); + public function _id(int $value): void { + $this->id = $value; } - public function _url(string $value, bool $validate = true) { + + public function _url(string $value, bool $validate = true): void { $this->hash = ''; $url = $value; if ($validate) { @@ -276,26 +283,26 @@ class FreshRSS_Feed extends Minz_Model { } $this->url = $url; } - public function _kind(int $value) { + + public function _kind(int $value): void { $this->kind = $value; } - /** @param FreshRSS_Category|null $cat */ - public function _category($cat) { + public function _category(?FreshRSS_Category $cat): void { $this->category = $cat; $this->categoryId = $this->category == null ? 0 : $this->category->id(); } /** @param int|string $id */ - public function _categoryId($id) { + public function _categoryId($id): void { $this->category = null; $this->categoryId = intval($id); } - public function _name(string $value) { + public function _name(string $value): void { $this->name = $value == '' ? '' : trim($value); } - public function _website(string $value, bool $validate = true) { + public function _website(string $value, bool $validate = true): void { if ($validate) { $value = checkUrl($value); } @@ -304,37 +311,37 @@ class FreshRSS_Feed extends Minz_Model { } $this->website = $value; } - public function _description(string $value) { + public function _description(string $value): void { $this->description = $value == '' ? '' : $value; } - public function _lastUpdate($value) { - $this->lastUpdate = intval($value); + public function _lastUpdate(int $value): void { + $this->lastUpdate = $value; } - public function _priority($value) { - $this->priority = intval($value); + public function _priority(int $value): void { + $this->priority = $value; } /** @param string $value HTML-encoded CSS selector */ - public function _pathEntries(string $value) { + public function _pathEntries(string $value): void { $this->pathEntries = $value; } - public function _httpAuth(string $value) { + public function _httpAuth(string $value): void { $this->httpAuth = $value; } - public function _error($value) { + /** @param bool|int $value */ + public function _error($value): void { $this->error = (bool)$value; } - public function _mute(bool $value) { + public function _mute(bool $value): void { $this->mute = $value; } - public function _ttl($value) { - $value = intval($value); + public function _ttl(int $value): void { $value = min($value, 100000000); $this->ttl = abs($value); $this->mute = $value < self::TTL_DEFAULT; } /** @param string|array<mixed>|bool|int|null $value Value, not HTML-encoded */ - public function _attributes(string $key, $value) { + public function _attributes(string $key, $value): void { if ($key == '') { if (is_string($value)) { $value = json_decode($value, true); @@ -349,17 +356,14 @@ class FreshRSS_Feed extends Minz_Model { } } - public function _nbNotRead($value) { - $this->nbNotRead = intval($value); + public function _nbNotRead(int $value): void { + $this->nbNotRead = $value; } - public function _nbEntries($value) { - $this->nbEntries = intval($value); + public function _nbEntries(int $value): void { + $this->nbEntries = $value; } - /** - * @return SimplePie|null - */ - public function load(bool $loadDetails = false, bool $noCache = false) { + public function load(bool $loadDetails = false, bool $noCache = false): ?SimplePie { if ($this->url != '') { // @phpstan-ignore-next-line if (CACHE_PATH === false) { @@ -440,7 +444,7 @@ class FreshRSS_Feed extends Minz_Model { /** * @return array<string> */ - public function loadGuids(SimplePie $simplePie) { + public function loadGuids(SimplePie $simplePie): array { $hasUniqueGuids = true; $testGuids = []; $guids = []; @@ -474,6 +478,9 @@ class FreshRSS_Feed extends Minz_Model { return $guids; } + /** + * @return iterable<FreshRSS_Entry> + */ public function loadEntries(SimplePie $simplePie) { $hasBadGuids = $this->attributes('hasBadGuids'); @@ -591,10 +598,7 @@ class FreshRSS_Feed extends Minz_Model { } } - /** - * @return SimplePie|null - */ - public function loadHtmlXpath() { + public function loadHtmlXpath(): ?SimplePie { if ($this->url == '') { return null; } @@ -708,7 +712,7 @@ class FreshRSS_Feed extends Minz_Model { if ($item['title'] != '' || $item['content'] != '' || $item['link'] != '') { // HTML-encoding/escaping of the relevant fields (all except 'content') foreach (['author', 'categories', 'guid', 'link', 'thumbnail', 'timestamp', 'title'] as $key) { - if (!empty($item[$key])) { + if (!empty($item[$key]) && is_string($item[$key])) { $item[$key] = Minz_Helper::htmlspecialchars_utf8($item[$key]); } } @@ -731,7 +735,7 @@ class FreshRSS_Feed extends Minz_Model { /** * To keep track of some new potentially unread articles since last commit+fetch from database */ - public function incPendingUnread(int $n = 1) { + public function incPendingUnread(int $n = 1): void { $this->nbPendingNotRead += $n; } @@ -770,6 +774,7 @@ class FreshRSS_Feed extends Minz_Model { /** * Remember to call updateCachedValue($id_feed) or updateCachedValues() just after + * @return int|false */ public function cleanOldEntries() { $archiving = $this->attributes('archiving'); @@ -785,7 +790,6 @@ class FreshRSS_Feed extends Minz_Model { $entryDAO = FreshRSS_Factory::createEntryDao(); $nb = $entryDAO->cleanOldEntries($this->id(), $archiving); if ($nb > 0) { - $needFeedCacheRefresh = true; Minz_Log::debug($nb . ' entries cleaned in feed [' . $this->url(false) . '] with: ' . json_encode($archiving)); } return $nb; @@ -793,6 +797,7 @@ class FreshRSS_Feed extends Minz_Model { return false; } + /** @param array<string,mixed> $attributes */ public static function cacheFilename(string $url, array $attributes, int $kind = FreshRSS_Feed::KIND_RSS): string { $simplePie = customSimplePie($attributes); $filename = $simplePie->get_cache_filename($url); @@ -851,12 +856,12 @@ class FreshRSS_Feed extends Minz_Model { } /** - * @param array<FreshRSS_FilterAction> $filterActions + * @param array<FreshRSS_FilterAction>|null $filterActions */ - private function _filterActions($filterActions) { + private function _filterActions(?array $filterActions): void { $this->filterActions = $filterActions; if (is_array($this->filterActions) && !empty($this->filterActions)) { - $this->_attributes('filters', array_map(function ($af) { + $this->_attributes('filters', array_map(static function (?FreshRSS_FilterAction $af) { return $af == null ? null : $af->toJSON(); }, $this->filterActions)); } else { @@ -885,10 +890,10 @@ class FreshRSS_Feed extends Minz_Model { /** * @param array<string> $filters */ - public function _filtersAction(string $action, $filters) { + public function _filtersAction(string $action, array $filters): void { $action = trim($action); if ($action == '' || !is_array($filters)) { - return false; + return; } $filters = array_unique(array_map('trim', $filters)); $filterActions = $this->filterActions(); diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php index 9138f3d59..837fef7f1 100644 --- a/app/Models/FeedDAO.php +++ b/app/Models/FeedDAO.php @@ -268,7 +268,7 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo { * @param bool|null $muted to include only muted feeds * @return int|false */ - public function deleteFeedByCategory(int $id, $muted = null) { + public function deleteFeedByCategory(int $id, ?bool $muted = null) { $sql = 'DELETE FROM `_feed` WHERE category=?'; if ($muted) { $sql .= ' AND ttl < 0'; @@ -338,7 +338,7 @@ SQL; } /** @return array<string,string> */ - public function listFeedsNewestItemUsec(?int $id_feed = null) { + public function listFeedsNewestItemUsec(?int $id_feed = null): array { $sql = 'SELECT id_feed, MAX(id) as newest_item_us FROM `_entry` '; if ($id_feed === null) { $sql .= 'GROUP BY id_feed'; @@ -358,7 +358,7 @@ SQL; * Use $defaultCacheDuration == -1 to return all feeds, without filtering them by TTL. * @return array<FreshRSS_Feed> */ - public function listFeedsOrderUpdate(int $defaultCacheDuration = 3600, int $limit = 0) { + public function listFeedsOrderUpdate(int $defaultCacheDuration = 3600, int $limit = 0): array { $this->updateTTL(); $sql = 'SELECT id, url, kind, name, website, `lastUpdate`, `pathEntries`, `httpAuth`, ttl, attributes ' . 'FROM `_feed` ' @@ -398,7 +398,7 @@ SQL; * @param bool|null $muted to include only muted feeds * @return array<FreshRSS_Feed> */ - public function listByCategory(int $cat, $muted = null): array { + public function listByCategory(int $cat, ?bool $muted = null): array { $sql = 'SELECT * FROM `_feed` WHERE category=?'; if ($muted) { $sql .= ' AND ttl < 0'; diff --git a/app/Models/Search.php b/app/Models/Search.php index 14d77cb6f..f5b061512 100644 --- a/app/Models/Search.php +++ b/app/Models/Search.php @@ -234,11 +234,11 @@ class FreshRSS_Search { } /** - * @param array<string> $anArray + * @param array<string>|null $anArray * @return array<string> */ - private static function removeEmptyValues($anArray): array { - return empty($anArray) ? [] : array_filter($anArray, function($value) { return $value !== ''; }); + private static function removeEmptyValues(?array $anArray): array { + return empty($anArray) ? [] : array_filter($anArray, static function(string $value) { return $value !== ''; }); } /** diff --git a/app/Models/Share.php b/app/Models/Share.php index 7bd6de9cf..b01d285f3 100644 --- a/app/Models/Share.php +++ b/app/Models/Share.php @@ -49,7 +49,7 @@ class FreshRSS_Share { self::register($share_options); } - uasort(self::$list_sharing, function ($a, $b) { + uasort(self::$list_sharing, static function (FreshRSS_Share $a, FreshRSS_Share $b) { return strcasecmp($a->name(), $b->name()); }); } @@ -303,7 +303,7 @@ class FreshRSS_Share { * @param array<string> $transform an array containing a list of functions to apply. * @return string the transformed data. */ - private static function transform(string $data, $transform): string { + private static function transform(string $data, array $transform): string { if (!is_array($transform) || empty($transform)) { return $data; } diff --git a/app/Models/StatsDAO.php b/app/Models/StatsDAO.php index 30d7aa2ef..a0a4ec498 100644 --- a/app/Models/StatsDAO.php +++ b/app/Models/StatsDAO.php @@ -13,7 +13,7 @@ class FreshRSS_StatsDAO extends Minz_ModelPdo { * * @return array{'main_stream':array{'total':int,'count_unreads':int,'count_reads':int,'count_favorites':int},'all_feeds':array{'total':int,'count_unreads':int,'count_reads':int,'count_favorites':int}} */ - public function calculateEntryRepartition() { + public function calculateEntryRepartition(): array { return array( 'main_stream' => $this->calculateEntryRepartitionPerFeed(null, true), 'all_feeds' => $this->calculateEntryRepartitionPerFeed(null, false), @@ -57,7 +57,7 @@ SQL; * Calculates entry count per day on a 30 days period. * @return array<int,int> */ - public function calculateEntryCount() { + public function calculateEntryCount(): array { $count = $this->initEntryCountArray(); $midnight = mktime(0, 0, 0); $oldest = $midnight - (self::ENTRY_COUNT_PERIOD * 86400); @@ -87,7 +87,7 @@ SQL; * Initialize an array for the entry count. * @return array<int,int> */ - protected function initEntryCountArray() { + protected function initEntryCountArray(): array { return $this->initStatsArray(-self::ENTRY_COUNT_PERIOD, -1); } @@ -348,8 +348,8 @@ SQL; * @param array<string> $data * @return array<string> */ - private function convertToTranslatedJson(array $data = array()) { - $translated = array_map(function($a) { + private function convertToTranslatedJson(array $data = array()): array { + $translated = array_map(static function (string $a) { return _t('gen.date.' . $a); }, $data); diff --git a/app/Models/StatsDAOPGSQL.php b/app/Models/StatsDAOPGSQL.php index 9548027ce..52a99d2f4 100644 --- a/app/Models/StatsDAOPGSQL.php +++ b/app/Models/StatsDAOPGSQL.php @@ -5,7 +5,7 @@ class FreshRSS_StatsDAOPGSQL extends FreshRSS_StatsDAO { /** * Calculates the number of article per hour of the day per feed * - * @param integer $feed id + * @param int $feed id * @return array<int,int> */ public function calculateEntryRepartitionPerFeedPerHour(?int $feed = null): array { @@ -48,6 +48,9 @@ ORDER BY period ASC SQL; $stm = $this->pdo->query($sql); + if ($stm === false) { + return []; + } $res = $stm->fetchAll(PDO::FETCH_NAMED); switch ($period) { diff --git a/app/Models/StatsDAOSQLite.php b/app/Models/StatsDAOSQLite.php index 632fa17e2..9f292aae6 100644 --- a/app/Models/StatsDAOSQLite.php +++ b/app/Models/StatsDAOSQLite.php @@ -25,6 +25,9 @@ ORDER BY period ASC SQL; $stm = $this->pdo->query($sql); + if ($stm === false) { + return []; + } $res = $stm->fetchAll(PDO::FETCH_NAMED); switch ($period) { diff --git a/app/Models/Tag.php b/app/Models/Tag.php index d88f0c1c2..4ab28a286 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -97,7 +97,7 @@ class FreshRSS_Tag extends Minz_Model { } /** - * @param string|int$value + * @param string|int $value */ public function _nbUnread($value): void { $this->nbUnread = (int)$value; diff --git a/app/Models/TagDAO.php b/app/Models/TagDAO.php index c27a69f11..0f491e706 100644 --- a/app/Models/TagDAO.php +++ b/app/Models/TagDAO.php @@ -245,7 +245,7 @@ SQL; } /** @return array<string,string> */ - public function listTagsNewestItemUsec(?int $id_tag = null) { + public function listTagsNewestItemUsec(?int $id_tag = null): array { $sql = 'SELECT t.id AS id_tag, MAX(e.id) AS newest_item_us ' . 'FROM `_tag` t ' . 'LEFT OUTER JOIN `_entrytag` et ON et.id_tag = t.id ' @@ -440,7 +440,7 @@ SQL; * @param array<array<string,string|int>>|array<string,string|int> $listDAO * @return array<FreshRSS_Tag> */ - private static function daoToTag(array $listDAO) { + private static function daoToTag(array $listDAO): array { $list = array(); if (!is_array($listDAO)) { $listDAO = array($listDAO); diff --git a/app/Models/TagDAOSQLite.php b/app/Models/TagDAOSQLite.php index 910455546..50683cf84 100644 --- a/app/Models/TagDAOSQLite.php +++ b/app/Models/TagDAOSQLite.php @@ -10,7 +10,7 @@ class FreshRSS_TagDAOSQLite extends FreshRSS_TagDAO { protected function autoUpdateDb(array $errorInfo): bool { if ($tableInfo = $this->pdo->query("SELECT sql FROM sqlite_master where name='tag'")) { $showCreate = $tableInfo->fetchColumn(); - if (stripos($showCreate, 'tag') === false) { + if (is_string($showCreate) && stripos($showCreate, 'tag') === false) { return $this->createTagTable(); //v1.12.0 } } diff --git a/app/Models/UserQuery.php b/app/Models/UserQuery.php index 278074362..f0d809378 100644 --- a/app/Models/UserQuery.php +++ b/app/Models/UserQuery.php @@ -34,7 +34,7 @@ class FreshRSS_UserQuery { private $tag_dao; /** - * @param array<string,string> $query + * @param array<string,string|int> $query */ public function __construct(array $query, FreshRSS_FeedDAO $feed_dao = null, FreshRSS_CategoryDAO $category_dao = null, FreshRSS_TagDAO $tag_dao = null) { $this->category_dao = $category_dao; diff --git a/app/Models/View.php b/app/Models/View.php index e908bdfad..87302a4e1 100644 --- a/app/Models/View.php +++ b/app/Models/View.php @@ -57,7 +57,7 @@ class FreshRSS_View extends Minz_View { public $show_email_field; /** @var string */ public $username; - /** @var array<array{'last_user_activity':int, 'language':string,'enabled':bool,'is_admin':bool, 'enabled':bool, 'article_count':int, 'database_size':int, 'last_user_activity', 'mail_login':string, 'feed_count':int, 'is_default':bool}> */ + /** @var array<array{'last_user_activity':int,'language':string,'enabled':bool,'is_admin':bool,'enabled':bool,'article_count':int,'database_size':int,'last_user_activity','mail_login':string,'feed_count':int,'is_default':bool}> */ public $users; // Updates @@ -73,7 +73,7 @@ class FreshRSS_View extends Minz_View { public $status_database; // Archiving - /** @var int|false */ + /** @var int */ public $nb_total; /** @var int */ public $size_total; diff --git a/app/Services/ExportService.php b/app/Services/ExportService.php index fd5d48f72..10d5ca2cc 100644 --- a/app/Services/ExportService.php +++ b/app/Services/ExportService.php @@ -87,8 +87,8 @@ class FreshRSS_Export_Service { /** * Generate the entries file content for the given feed. - * @param integer $feed_id - * @param integer $max_number_entries + * @param int $feed_id + * @param int $max_number_entries * @return array{0:string,1:string}|null First item is the filename, second item is the content. * It also can return null if the feed doesn’t exist. */ diff --git a/app/Services/ImportService.php b/app/Services/ImportService.php index 6f6ca13ac..3707e4c5e 100644 --- a/app/Services/ImportService.php +++ b/app/Services/ImportService.php @@ -15,10 +15,8 @@ class FreshRSS_Import_Service { /** * Initialize the service for the given user. - * - * @param string $username */ - public function __construct($username = null) { + public function __construct(?string $username = null) { $this->catDAO = FreshRSS_Factory::createCategoryDao($username); $this->feedDAO = FreshRSS_Factory::createFeedDao($username); } @@ -33,9 +31,9 @@ class FreshRSS_Import_Service { * * @param string $opml_file the OPML file content. * @param FreshRSS_Category|null $forced_category force the feeds to be associated to this category. - * @param boolean $dry_run true to not create categories and feeds in database. + * @param bool $dry_run true to not create categories and feeds in database. */ - public function importOpml(string $opml_file, $forced_category = null, $dry_run = false) { + public function importOpml(string $opml_file, ?FreshRSS_Category $forced_category = null, bool $dry_run = false): void { @set_time_limit(300); $this->lastStatus = true; $opml_array = array(); @@ -132,20 +130,17 @@ class FreshRSS_Import_Service { } } } - - return; } /** * Create a feed from a feed element (i.e. OPML outline). * - * @param array<string, string> $feed_elt An OPML element (must be a feed element). + * @param array<string,string> $feed_elt An OPML element (must be a feed element). * @param FreshRSS_Category $category The category to associate to the feed. - * @param boolean $dry_run true to not create the feed in database. - * + * @param bool $dry_run true to not create the feed in database. * @return FreshRSS_Feed|null The created feed, or null if it failed. */ - private function createFeed($feed_elt, $category, $dry_run) { + private function createFeed(array $feed_elt, FreshRSS_Category $category, bool $dry_run): ?FreshRSS_Feed { $url = Minz_Helper::htmlspecialchars_utf8($feed_elt['xmlUrl']); $name = $feed_elt['text'] ?? $feed_elt['title'] ?? ''; $name = Minz_Helper::htmlspecialchars_utf8($name); @@ -256,12 +251,11 @@ class FreshRSS_Import_Service { /** * Create and return a category. * - * @param array<string, string> $category_element An OPML element (must be a category element). - * @param boolean $dry_run true to not create the category in database. - * + * @param array<string,string> $category_element An OPML element (must be a category element). + * @param bool $dry_run true to not create the category in database. * @return FreshRSS_Category|null The created category, or null if it failed. */ - private function createCategory($category_element, $dry_run) { + private function createCategory(array $category_element, bool $dry_run): ?FreshRSS_Category { $name = $category_element['text'] ?? $category_element['title'] ?? ''; $name = Minz_Helper::htmlspecialchars_utf8($name); $category = new FreshRSS_Category($name); @@ -295,14 +289,13 @@ class FreshRSS_Import_Service { * This method is applied to a list of outlines. It merges the different * list of feeds from several outlines into one array. * - * @param array $outlines + * @param array<mixed> $outlines * The outlines from which to extract the outlines. * @param string $parent_category_name * The name of the parent category of the current outlines. - * - * @return array[] + * @return array{0:array<mixed>,1:array<mixed>} */ - private function loadFromOutlines($outlines, $parent_category_name) { + private function loadFromOutlines(array $outlines, string $parent_category_name): array { $categories_elements = []; $categories_to_feeds = []; @@ -342,14 +335,14 @@ class FreshRSS_Import_Service { * exists), it will add the outline to an array accessible by its category * name. * - * @param array $outline + * @param array<mixed> $outline * The outline from which to extract the categories and feeds outlines. * @param string $parent_category_name * The name of the parent category of the current outline. * - * @return array[] + * @return array{0:array<string,mixed>,1:array<string,mixed>} */ - private function loadFromOutline($outline, $parent_category_name) { + private function loadFromOutline($outline, $parent_category_name): array { $categories_elements = []; $categories_to_feeds = []; @@ -396,7 +389,7 @@ class FreshRSS_Import_Service { return [$categories_elements, $categories_to_feeds]; } - private static function log($message) { + private static function log(string $message): void { if (FreshRSS_Context::$isCli) { fwrite(STDERR, "FreshRSS error during OPML import: {$message}\n"); } else { diff --git a/app/Utils/feverUtil.php b/app/Utils/feverUtil.php index 0e4b712ce..4de321732 100644 --- a/app/Utils/feverUtil.php +++ b/app/Utils/feverUtil.php @@ -57,7 +57,7 @@ class FreshRSS_fever_Util { * * @return bool true if the deletion succeeded, else false. */ - public static function deleteKey(string $username) { + public static function deleteKey(string $username): bool { $userConfig = get_user_configuration($username); if ($userConfig === null) { return false; diff --git a/app/actualize_script.php b/app/actualize_script.php index 4a38c13f7..160911f53 100755 --- a/app/actualize_script.php +++ b/app/actualize_script.php @@ -54,7 +54,7 @@ if (($handle = @fopen($mutexFile, 'x')) === false) { } fclose($handle); -register_shutdown_function(function () use ($mutexFile) { +register_shutdown_function(static function () use ($mutexFile) { unlink($mutexFile); }); // </Mutex> @@ -63,7 +63,7 @@ notice('FreshRSS starting feeds actualization at ' . $begin_date->format('c')); // make sure the PHP setup of the CLI environment is compatible with FreshRSS as well echo 'Failed requirements!', "\n"; -performRequirementCheck(FreshRSS_Context::$system_conf->db['type']); +performRequirementCheck(FreshRSS_Context::$system_conf->db['type'] ?? ''); ob_clean(); echo 'Results: ', "\n"; //Buffered @@ -100,7 +100,7 @@ foreach ($users as $user) { // NB: Extensions and hooks are reinitialised there $app->init(); - Minz_ExtensionManager::addHook('feed_before_actualize', function ($feed) use ($mutexFile) { + Minz_ExtensionManager::addHook('feed_before_actualize', static function (FreshRSS_Feed $feed) use ($mutexFile) { touch($mutexFile); return $feed; }); diff --git a/app/install.php b/app/install.php index b43aa81bb..599fd9863 100644 --- a/app/install.php +++ b/app/install.php @@ -18,7 +18,11 @@ if (STEP === 2 && isset($_POST['type'])) { Minz_Session::_param('bd_type', $_POST['type']); } -function param($key, $default = false) { +/** + * @param mixed $default + * @return mixed + */ +function param(string $key, $default = false) { if (isset($_POST[$key])) { return $_POST[$key]; } else { @@ -27,7 +31,7 @@ function param($key, $default = false) { } // gestion internationalisation -function initTranslate() { +function initTranslate(): void { Minz_Translate::init(); $available_languages = Minz_Translate::availableLanguages(); @@ -42,14 +46,14 @@ function initTranslate() { Minz_Translate::reset(Minz_Session::param('language')); } -function get_best_language() { +function get_best_language(): string { $accept = empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? '' : $_SERVER['HTTP_ACCEPT_LANGUAGE']; return strtolower(substr($accept, 0, 2)); } /*** SAUVEGARDES ***/ -function saveLanguage() { +function saveLanguage(): bool { if (!empty($_POST)) { if (!isset($_POST['language'])) { return false; @@ -60,9 +64,10 @@ function saveLanguage() { header('Location: index.php?step=1'); } + return true; } -function saveStep1() { +function saveStep1(): void { if (isset($_POST['freshrss-keep-install']) && $_POST['freshrss-keep-install'] === '1') { // We want to keep our previous installation of FreshRSS @@ -79,12 +84,12 @@ function saveStep1() { 'auth_type' => FreshRSS_Context::$system_conf->auth_type, 'default_user' => Minz_User::name(), 'passwordHash' => FreshRSS_Context::$user_conf->passwordHash, - 'bd_type' => FreshRSS_Context::$system_conf->db['type'], - 'bd_host' => FreshRSS_Context::$system_conf->db['host'], - 'bd_user' => FreshRSS_Context::$system_conf->db['user'], - 'bd_password' => FreshRSS_Context::$system_conf->db['password'], - 'bd_base' => FreshRSS_Context::$system_conf->db['base'], - 'bd_prefix' => FreshRSS_Context::$system_conf->db['prefix'], + 'bd_type' => FreshRSS_Context::$system_conf->db['type'] ?? '', + 'bd_host' => FreshRSS_Context::$system_conf->db['host'] ?? '', + 'bd_user' => FreshRSS_Context::$system_conf->db['user'] ?? '', + 'bd_password' => FreshRSS_Context::$system_conf->db['password'] ?? '', + 'bd_base' => FreshRSS_Context::$system_conf->db['base'] ?? '', + 'bd_prefix' => FreshRSS_Context::$system_conf->db['prefix'] ?? '', 'bd_error' => false, ]); @@ -92,7 +97,7 @@ function saveStep1() { } } -function saveStep2() { +function saveStep2(): void { if (!empty($_POST)) { if (Minz_Session::param('bd_type') === 'sqlite') { Minz_Session::_params([ @@ -190,9 +195,9 @@ function saveStep2() { invalidateHttpCache(); } -function saveStep3() { +function saveStep3(): bool { if (!empty($_POST)) { - $system_default_config = Minz_Configuration::get('default_system'); + $system_default_config = FreshRSS_SystemConfiguration::get('default_system'); Minz_Session::_params([ 'title' => $system_default_config->title, 'auth_type' => param('auth_type', 'form'), @@ -242,10 +247,11 @@ function saveStep3() { header('Location: index.php?step=4'); } + return true; } /*** VÉRIFICATIONS ***/ -function checkStep() { +function checkStep(): void { $s0 = checkStep0(); $s1 = checkRequirements(); $s2 = checkStep2(); @@ -262,7 +268,8 @@ function checkStep() { Minz_Session::_param('actualize_feeds', true); } -function checkStep0() { +/** @return array<string,string> */ +function checkStep0(): array { $languages = Minz_Translate::availableLanguages(); $language = Minz_Session::param('language') != '' && in_array(Minz_Session::param('language'), $languages); $sessionWorking = Minz_Session::param('sessionWorking') === 'ok'; @@ -274,7 +281,7 @@ function checkStep0() { ); } -function freshrss_already_installed() { +function freshrss_already_installed(): bool { $conf_path = join_path(DATA_PATH, 'config.php'); if (!file_exists($conf_path)) { return false; @@ -300,7 +307,8 @@ function freshrss_already_installed() { return true; } -function checkStep2() { +/** @return array<string,string> */ +function checkStep2(): array { $conf = is_writable(join_path(DATA_PATH, 'config.php')); $bd = Minz_Session::param('bd_type') != ''; @@ -314,7 +322,8 @@ function checkStep2() { ]; } -function checkStep3() { +/** @return array<string,string> */ +function checkStep3(): array { $conf = Minz_Session::param('default_user') != ''; $form = Minz_Session::param('auth_type') != ''; @@ -335,7 +344,7 @@ function checkStep3() { /*** AFFICHAGE ***/ -function printStep0() { +function printStep0(): void { $actual = Minz_Translate::language(); $languages = Minz_Translate::availableLanguages(); $s0 = checkStep0(); @@ -373,7 +382,8 @@ function printStep0() { <?php } -function printStep1Template($key, $value, $messageParams = []) { +/** @param array<string> $messageParams */ +function printStep1Template(string $key, string $value, array $messageParams = []): void { if ('ok' === $value) { $message = _t("install.check.{$key}.ok", ...$messageParams); ?><p class="alert alert-success"><span class="alert-head"><?= _t('gen.short.ok') ?></span> <?= $message ?></p><?php @@ -383,10 +393,12 @@ function printStep1Template($key, $value, $messageParams = []) { } } -function getProcessUsername() { +function getProcessUsername(): string { if (function_exists('posix_getpwuid') && function_exists('posix_geteuid')) { - $processUser = posix_getpwuid(posix_geteuid()); - return $processUser['name']; + $processUser = posix_getpwuid(posix_geteuid()) ?: []; + if (!empty($processUser['name'])) { + return $processUser['name']; + } } if (function_exists('exec')) { @@ -400,7 +412,7 @@ function getProcessUsername() { } // @todo refactor this view with the check_install action -function printStep1() { +function printStep1(): void { $res = checkRequirements(); $processUsername = getProcessUsername(); ?> @@ -408,14 +420,10 @@ function printStep1() { <noscript><p class="alert alert-warn"><span class="alert-head"><?= _t('gen.short.attention') ?></span> <?= _t('install.javascript_is_better') ?></p></noscript> <?php - if (function_exists('curl_version')) { - $version = curl_version(); - } else { - $version['version'] = ''; - } + $version = function_exists('curl_version') ? curl_version() : []; printStep1Template('php', $res['php'], [PHP_VERSION, FRESHRSS_MIN_PHP_VERSION]); printStep1Template('pdo', $res['pdo']); - printStep1Template('curl', $res['curl'], [$version['version']]); + printStep1Template('curl', $res['curl'], [$version['version'] ?? '']); printStep1Template('json', $res['json']); printStep1Template('pcre', $res['pcre']); printStep1Template('ctype', $res['ctype']); @@ -466,8 +474,8 @@ function printStep1() { <?php } -function printStep2() { - $system_default_config = Minz_Configuration::get('default_system'); +function printStep2(): void { + $system_default_config = FreshRSS_SystemConfiguration::get('default_system'); $s2 = checkStep2(); if ($s2['all'] == 'ok') { ?> <p class="alert alert-success"><span class="alert-head"><?= _t('gen.short.ok') ?></span> <?= _t('install.bdd.conf.ok') ?></p> @@ -509,7 +517,7 @@ function printStep2() { <label class="group-name" for="host"><?= _t('install.bdd.host') ?></label> <div class="group-controls"> <input type="text" id="host" name="host" pattern="[0-9A-Z/a-z_.-]{1,64}(:[0-9]{2,5})?" value="<?= - isset($_SESSION['bd_host']) ? $_SESSION['bd_host'] : $system_default_config->db['host'] ?>" tabindex="2" /> + isset($_SESSION['bd_host']) ? $_SESSION['bd_host'] : ($system_default_config->db['host'] ?? '') ?>" tabindex="2" /> </div> </div> @@ -544,7 +552,7 @@ function printStep2() { <label class="group-name" for="prefix"><?= _t('install.bdd.prefix') ?></label> <div class="group-controls"> <input type="text" id="prefix" name="prefix" maxlength="16" pattern="[0-9A-Za-z_]{1,16}" value="<?= - isset($_SESSION['bd_prefix']) ? $_SESSION['bd_prefix'] : $system_default_config->db['prefix'] ?>" tabindex="7" /> + isset($_SESSION['bd_prefix']) ? $_SESSION['bd_prefix'] : ($system_default_config->db['prefix'] ?? '') ?>" tabindex="7" /> </div> </div> </div> @@ -562,11 +570,11 @@ function printStep2() { <?php } -function no_auth($auth_type) { +function no_auth(string $auth_type): bool { return !in_array($auth_type, array('form', 'http_auth', 'none')); } -function printStep3() { +function printStep3(): void { $auth_type = isset($_SESSION['auth_type']) ? $_SESSION['auth_type'] : ''; $s3 = checkStep3(); if ($s3['all'] == 'ok') { ?> @@ -628,7 +636,7 @@ function printStep3() { <?php } -function printStep4() { +function printStep4(): void { ?> <p class="alert alert-success"><span class="alert-head"><?= _t('install.congratulations') ?></span> <?= _t('install.ok') ?></p> <div class="form-group form-actions"> @@ -639,7 +647,7 @@ function printStep4() { <?php } -function printStep5() { +function printStep5(): void { ?> <p class="alert alert-error"> <span class="alert-head"><?= _t('gen.short.damn') ?></span> @@ -676,7 +684,7 @@ case 5: } ?> <!DOCTYPE html> -<html<?php +<html <?php if (_t('gen.dir') === 'rtl') { echo ' dir="rtl" class="rtl"'; } diff --git a/app/views/helpers/export/articles.phtml b/app/views/helpers/export/articles.phtml index cc6a62377..60041339b 100644 --- a/app/views/helpers/export/articles.phtml +++ b/app/views/helpers/export/articles.phtml @@ -11,7 +11,7 @@ $articles = array( 'items' => array(), ); -echo rtrim(json_encode($articles, $options), " ]}\n\r\t"), "\n"; +echo rtrim(json_encode($articles, $options) ?: '', " ]}\n\r\t"), "\n"; $first = true; if (empty($this->entryIdsTagNames)) { diff --git a/app/views/helpers/export/opml.phtml b/app/views/helpers/export/opml.phtml index 4df36b122..5acdff374 100644 --- a/app/views/helpers/export/opml.phtml +++ b/app/views/helpers/export/opml.phtml @@ -4,7 +4,7 @@ * @param array<FreshRSS_Feed> $feeds * @return array<array<string,string|null>> */ -function feedsToOutlines($feeds, bool $excludeMutedFeeds = false): array { +function feedsToOutlines(array $feeds, bool $excludeMutedFeeds = false): array { $outlines = []; foreach ($feeds as $feed) { if ($feed->mute() && $excludeMutedFeeds) { @@ -98,4 +98,6 @@ if (!empty($this->feeds)) { } $libopml = new \marienfressinaud\LibOpml\LibOpml(true); -echo $libopml->render($opml_array); +$opml = $libopml->render($opml_array); +/** @var string $opml */ +echo $opml; diff --git a/app/views/helpers/javascript_vars.phtml b/app/views/helpers/javascript_vars.phtml index e108f5a34..03ed96a9e 100644 --- a/app/views/helpers/javascript_vars.phtml +++ b/app/views/helpers/javascript_vars.phtml @@ -72,4 +72,4 @@ echo htmlspecialchars(json_encode(array( 'unread' => rawurlencode(_i('unread')), ), 'extensions' => $extData, -), JSON_UNESCAPED_UNICODE), ENT_NOQUOTES, 'UTF-8'); +), JSON_UNESCAPED_UNICODE) ?: '', ENT_NOQUOTES, 'UTF-8'); diff --git a/app/views/index/logs.phtml b/app/views/index/logs.phtml index 54b7e1c6b..42be022d6 100644 --- a/app/views/index/logs.phtml +++ b/app/views/index/logs.phtml @@ -14,7 +14,7 @@ ?> <?php if (!empty($items)) { ?> - <?php $this->logsPaginator->render('logs_pagination.phtml', 0); ?> + <?php $this->logsPaginator->render('logs_pagination.phtml'); ?> <div id="loglist-wrapper" class="table-wrapper"> <table id="loglist"> <thead> @@ -41,7 +41,7 @@ </tbody> </table> </div> - <?php $this->logsPaginator->render('logs_pagination.phtml', 0); ?> + <?php $this->logsPaginator->render('logs_pagination.phtml'); ?> diff --git a/app/views/index/normal.phtml b/app/views/index/normal.phtml index 02b336bf7..ede772a78 100644 --- a/app/views/index/normal.phtml +++ b/app/views/index/normal.phtml @@ -40,7 +40,7 @@ $today = @strtotime('today'); // We most likely already have the feed object in cache $this->feed = FreshRSS_CategoryDAO::findFeed($this->categories, $this->entry->feedId()); if ($this->feed == null) { - $this->feed = $this->entry->feed(); + $this->feed = $this->entry->feed() ?: null; if ($this->feed == null) { $this->feed = FreshRSS_Feed::example(); } diff --git a/app/views/stats/idle.phtml b/app/views/stats/idle.phtml index fcab1e8e3..d94256860 100644 --- a/app/views/stats/idle.phtml +++ b/app/views/stats/idle.phtml @@ -45,7 +45,7 @@ <li class="item feed<?= $error_class, $empty_class, $mute_class ?>" title="<?= $error_title, $empty_title ?>"> <a class="configure open-slider" href="<?= _url('stats', 'feed', 'id', $feedInPeriod['id'], 'sub', 'idle') ?>" title="<?= _t('gen.action.manage') ?>"><?= _i('configure') ?></a> <?php if (FreshRSS_Context::$user_conf->show_favicons): ?><img class="favicon" src="<?= $feedInPeriod['favicon'] ?>" alt="✇" loading="lazy" /><?php endif; ?> - <span title="<?= timestamptodate($feedInPeriod['last_date'], false) ?>"><?= $feedInPeriod['name'] ?> + <span title="<?= timestamptodate((int)($feedInPeriod['last_date']), false) ?>"><?= $feedInPeriod['name'] ?> (<?= _t('admin.stats.number_entries', $feedInPeriod['nb_articles']) ?>)</span> </li> <?php } ?> |
