mirror of https://github.com/FreshRSS/FreshRSS.git
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
This commit is contained in:
parent
41fa4e746d
commit
f3760f138d
|
@ -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);
|
||||
|
|
|
@ -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])) {
|
||||
|
|
|
@ -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'];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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'",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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() ?: [];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 = [];
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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 !== ''; });
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
|
|
|
@ -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"';
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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'); ?>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 } ?>
|
||||
|
|
|
@ -77,10 +77,10 @@ function performRequirementCheck(string $databaseType): void {
|
|||
* @return array<string>
|
||||
*/
|
||||
function getLongOptions(array $options, string $regex): array {
|
||||
$longOptions = array_filter($options, function($a) use ($regex) {
|
||||
$longOptions = array_filter($options, static function (string $a) use ($regex) {
|
||||
return preg_match($regex, $a);
|
||||
});
|
||||
return array_map(function($a) use ($regex) {
|
||||
return array_map(static function (string $a) use ($regex) {
|
||||
return preg_replace($regex, '', $a);
|
||||
}, $longOptions);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
require(__DIR__ . '/_cli.php');
|
||||
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type']);
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type'] ?? '');
|
||||
|
||||
$params = array(
|
||||
'user:',
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<?php
|
||||
require(__DIR__ . '/_cli.php');
|
||||
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type']);
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type'] ?? '');
|
||||
|
||||
$params = array(
|
||||
'user:',
|
||||
|
@ -10,7 +10,7 @@ $params = array(
|
|||
|
||||
$options = getopt('', $params);
|
||||
|
||||
if (!validateOptions($argv, $params) || empty($options['user'])) {
|
||||
if (!validateOptions($argv, $params) || empty($options['user']) || !is_string($options['user'])) {
|
||||
fail('Usage: ' . basename(__FILE__) . " --user username");
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<?php
|
||||
require(__DIR__ . '/_cli.php');
|
||||
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type']);
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type'] ?? '');
|
||||
|
||||
$params = array(
|
||||
'user:',
|
||||
|
@ -10,7 +10,7 @@ $params = array(
|
|||
|
||||
$options = getopt('', $params);
|
||||
|
||||
if (!validateOptions($argv, $params) || empty($options['user'])) {
|
||||
if (!validateOptions($argv, $params) || empty($options['user']) || !is_string($options['user'])) {
|
||||
fail('Usage: ' . basename(__FILE__) . " --user username");
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<?php
|
||||
require(__DIR__ . '/_cli.php');
|
||||
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type']);
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type'] ?? '');
|
||||
|
||||
$params = array(
|
||||
'user:',
|
||||
|
@ -10,7 +10,7 @@ $params = array(
|
|||
|
||||
$options = getopt('', $params);
|
||||
|
||||
if (!validateOptions($argv, $params) || empty($options['user'])) {
|
||||
if (!validateOptions($argv, $params) || empty($options['user']) || !is_string($options['user'])) {
|
||||
fail('Usage: ' . basename(__FILE__) . " --user username");
|
||||
}
|
||||
$username = $options['user'];
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<?php
|
||||
require(__DIR__ . '/_cli.php');
|
||||
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type']);
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type'] ?? '');
|
||||
|
||||
$params = array(
|
||||
'user:',
|
||||
|
@ -10,7 +10,7 @@ $params = array(
|
|||
|
||||
$options = getopt('', $params);
|
||||
|
||||
if (!validateOptions($argv, $params) || empty($options['user'])) {
|
||||
if (!validateOptions($argv, $params) || empty($options['user']) || !is_string($options['user'])) {
|
||||
fail('Usage: ' . basename(__FILE__) . " --user username > /path/to/file.opml.xml");
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<?php
|
||||
require(__DIR__ . '/_cli.php');
|
||||
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type']);
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type'] ?? '');
|
||||
|
||||
$params = [
|
||||
'user:',
|
||||
|
@ -11,7 +11,7 @@ $params = [
|
|||
|
||||
$options = getopt('', $params);
|
||||
|
||||
if (!validateOptions($argv, $params) || empty($options['user']) || empty($options['filename'])) {
|
||||
if (!validateOptions($argv, $params) || empty($options['user']) || empty($options['filename']) || !is_string($options['user']) || !is_string($options['filename'])) {
|
||||
fail('Usage: ' . basename(__FILE__) . ' --user username --filename /path/to/db.sqlite');
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<?php
|
||||
require(__DIR__ . '/_cli.php');
|
||||
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type']);
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type'] ?? '');
|
||||
|
||||
$params = array(
|
||||
'user:',
|
||||
|
@ -11,7 +11,7 @@ $params = array(
|
|||
|
||||
$options = getopt('', $params);
|
||||
|
||||
if (!validateOptions($argv, $params) || empty($options['user'])) {
|
||||
if (!validateOptions($argv, $params) || empty($options['user']) || !is_string($options['user'])) {
|
||||
fail('Usage: ' . basename(__FILE__) . " --user username ( --max-feed-entries 100 ) > /path/to/file.zip");
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ class I18nData {
|
|||
* the parent key is 'a.b.c.d'.
|
||||
*/
|
||||
private function getParentKey(string $key): string {
|
||||
return substr($key, 0, strrpos($key, '.'));
|
||||
return substr($key, 0, strrpos($key, '.') ?: null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -183,7 +183,7 @@ class I18nData {
|
|||
}
|
||||
|
||||
$keys = array_keys($this->data[static::REFERENCE_LANGUAGE][$this->getFilenamePrefix($key)]);
|
||||
$children = array_values(array_filter($keys, function ($element) use ($key) {
|
||||
$children = array_values(array_filter($keys, static function (string $element) use ($key) {
|
||||
if ($element === $key) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<?php
|
||||
require(__DIR__ . '/_cli.php');
|
||||
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type']);
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type'] ?? '');
|
||||
|
||||
$params = array(
|
||||
'user:',
|
||||
|
@ -11,7 +11,7 @@ $params = array(
|
|||
|
||||
$options = getopt('', $params);
|
||||
|
||||
if (!validateOptions($argv, $params) || empty($options['user']) || empty($options['filename'])) {
|
||||
if (!validateOptions($argv, $params) || empty($options['user']) || empty($options['filename']) || !is_string($options['user']) || !is_string($options['filename'])) {
|
||||
fail('Usage: ' . basename(__FILE__) . " --user username --filename /path/to/file.ext");
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<?php
|
||||
require(__DIR__ . '/_cli.php');
|
||||
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type']);
|
||||
performRequirementCheck(FreshRSS_Context::$system_conf->db['type'] ?? '');
|
||||
|
||||
$params = [
|
||||
'user:',
|
||||
|
@ -12,7 +12,7 @@ $params = [
|
|||
|
||||
$options = getopt('', $params);
|
||||
|
||||
if (!validateOptions($argv, $params) || empty($options['user']) || empty($options['filename'])) {
|
||||
if (!validateOptions($argv, $params) || empty($options['user']) || empty($options['filename']) || !is_string($options['user']) || !is_string($options['filename'])) {
|
||||
fail('Usage: ' . basename(__FILE__) . ' --user username --force-overwrite --filename /path/to/db.sqlite');
|
||||
}
|
||||
|
||||
|
|
|
@ -71,12 +71,12 @@ foreach ($users as $username) {
|
|||
'enabled' => FreshRSS_Context::$user_conf->enabled ? '*' : '',
|
||||
'last_user_activity' => FreshRSS_UserDAO::mtime($username),
|
||||
'database_size' => $databaseDAO->size(),
|
||||
'categories' => (int) $catDAO->count(),
|
||||
'feeds' => (int) count($feedDAO->listFeedsIds()),
|
||||
'reads' => (int) $nbEntries['read'],
|
||||
'unreads' => (int) $nbEntries['unread'],
|
||||
'favourites' => (int) $nbFavorites['all'],
|
||||
'tags' => (int) $tagDAO->count(),
|
||||
'categories' => $catDAO->count(),
|
||||
'feeds' => count($feedDAO->listFeedsIds()),
|
||||
'reads' => (int)$nbEntries['read'],
|
||||
'unreads' => (int)$nbEntries['unread'],
|
||||
'favourites' => (int)$nbFavorites['all'],
|
||||
'tags' => (int)$tagDAO->count(),
|
||||
'lang' => FreshRSS_Context::$user_conf->language,
|
||||
'mail_login' => FreshRSS_Context::$user_conf->mail_login,
|
||||
);
|
||||
|
|
|
@ -49,7 +49,8 @@
|
|||
"ext-phar": "*",
|
||||
"ext-tokenizer": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"phpstan/phpstan": "~1.9.17",
|
||||
"phpstan/phpstan": "~1.10.13",
|
||||
"phpstan/phpstan-phpunit": "^1.3",
|
||||
"phpunit/phpunit": "^9",
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
|
@ -59,7 +60,7 @@
|
|||
"phpcs": "phpcs . -s",
|
||||
"phpcbf": "phpcbf . -p -s",
|
||||
"phpstan": "phpstan analyse --memory-limit 512M .",
|
||||
"phpstan-next": "phpstan analyse --level 6 --memory-limit 512M $(find . -type d -name 'vendor' -prune -o -name '*.php' -o -name '*.phtml' | grep -Fxvf ./tests/phpstan-next.txt | sort | paste -s)",
|
||||
"phpstan-next": "phpstan analyse --level 7 --memory-limit 512M $(find . -type d -name 'vendor' -prune -o -name '*.php' -o -name '*.phtml' | grep -Fxvf ./tests/phpstan-next.txt | sort | paste -s)",
|
||||
"phpunit": "phpunit --bootstrap ./tests/bootstrap.php --verbose ./tests",
|
||||
"translations": "cli/manipulate.translation.php -a format",
|
||||
"test": [
|
||||
|
@ -74,5 +75,10 @@
|
|||
"@translations",
|
||||
"@phpcbf"
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"phpstan/extension-installer": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,35 +4,35 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "4dcbcd3ba9c1dbed63612651a725dab8",
|
||||
"content-hash": "194c10da954d3f120fef1e0b21c34546",
|
||||
"packages": [],
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "doctrine/instantiator",
|
||||
"version": "1.5.0",
|
||||
"version": "2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/instantiator.git",
|
||||
"reference": "0a0fa9780f5d4e507415a065172d26a98d02047b"
|
||||
"reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b",
|
||||
"reference": "0a0fa9780f5d4e507415a065172d26a98d02047b",
|
||||
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
|
||||
"reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0"
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^9 || ^11",
|
||||
"doctrine/coding-standard": "^11",
|
||||
"ext-pdo": "*",
|
||||
"ext-phar": "*",
|
||||
"phpbench/phpbench": "^0.16 || ^1",
|
||||
"phpstan/phpstan": "^1.4",
|
||||
"phpstan/phpstan-phpunit": "^1",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
|
||||
"vimeo/psalm": "^4.30 || ^5.4"
|
||||
"phpbench/phpbench": "^1.2",
|
||||
"phpstan/phpstan": "^1.9.4",
|
||||
"phpstan/phpstan-phpunit": "^1.3",
|
||||
"phpunit/phpunit": "^9.5.27",
|
||||
"vimeo/psalm": "^5.4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
@ -59,7 +59,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/instantiator/issues",
|
||||
"source": "https://github.com/doctrine/instantiator/tree/1.5.0"
|
||||
"source": "https://github.com/doctrine/instantiator/tree/2.0.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -75,20 +75,20 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-12-30T00:15:36+00:00"
|
||||
"time": "2022-12-30T00:23:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
"version": "1.11.0",
|
||||
"version": "1.11.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||
"reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
|
||||
"reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
|
||||
"reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
|
||||
"reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -126,7 +126,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/myclabs/DeepCopy/issues",
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.11.0"
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.11.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -134,20 +134,20 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-03T13:19:32+00:00"
|
||||
"time": "2023-03-08T13:26:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "v4.15.2",
|
||||
"version": "v4.15.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||
"reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc"
|
||||
"reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc",
|
||||
"reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6bb5176bc4af8bcb7d926f88718db9b96a2d4290",
|
||||
"reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -188,9 +188,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2"
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.15.4"
|
||||
},
|
||||
"time": "2022-11-12T15:38:23+00:00"
|
||||
"time": "2023-03-05T19:49:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
|
@ -305,16 +305,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "1.9.17",
|
||||
"version": "1.10.13",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "204e459e7822f2c586463029f5ecec31bb45a1f2"
|
||||
"reference": "f07bf8c6980b81bf9e49d44bd0caf2e737614a70"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/204e459e7822f2c586463029f5ecec31bb45a1f2",
|
||||
"reference": "204e459e7822f2c586463029f5ecec31bb45a1f2",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/f07bf8c6980b81bf9e49d44bd0caf2e737614a70",
|
||||
"reference": "f07bf8c6980b81bf9e49d44bd0caf2e737614a70",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -343,8 +343,11 @@
|
|||
"static analysis"
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://phpstan.org/user-guide/getting-started",
|
||||
"forum": "https://github.com/phpstan/phpstan/discussions",
|
||||
"issues": "https://github.com/phpstan/phpstan/issues",
|
||||
"source": "https://github.com/phpstan/phpstan/tree/1.9.17"
|
||||
"security": "https://github.com/phpstan/phpstan/security/policy",
|
||||
"source": "https://github.com/phpstan/phpstan-src"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -360,27 +363,79 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-02-08T12:25:00+00:00"
|
||||
"time": "2023-04-12T19:29:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "9.2.23",
|
||||
"name": "phpstan/phpstan-phpunit",
|
||||
"version": "1.3.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c"
|
||||
"url": "https://github.com/phpstan/phpstan-phpunit.git",
|
||||
"reference": "9e1b9de6d260461f6e99b6a8f2dbb0bbb98b579c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c",
|
||||
"reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/9e1b9de6d260461f6e99b6a8f2dbb0bbb98b579c",
|
||||
"reference": "9e1b9de6d260461f6e99b6a8f2dbb0bbb98b579c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"phpstan/phpstan": "^1.10"
|
||||
},
|
||||
"conflict": {
|
||||
"phpunit/phpunit": "<7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"nikic/php-parser": "^4.13.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||
"phpstan/phpstan-strict-rules": "^1.0",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"type": "phpstan-extension",
|
||||
"extra": {
|
||||
"phpstan": {
|
||||
"includes": [
|
||||
"extension.neon",
|
||||
"rules.neon"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PHPStan\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "PHPUnit extensions and rules for PHPStan",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpstan-phpunit/issues",
|
||||
"source": "https://github.com/phpstan/phpstan-phpunit/tree/1.3.11"
|
||||
},
|
||||
"time": "2023-03-25T19:42:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "9.2.26",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/443bc6912c9bd5b409254a40f4b0f4ced7c80ea1",
|
||||
"reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"nikic/php-parser": "^4.14",
|
||||
"nikic/php-parser": "^4.15",
|
||||
"php": ">=7.3",
|
||||
"phpunit/php-file-iterator": "^3.0.3",
|
||||
"phpunit/php-text-template": "^2.0.2",
|
||||
|
@ -395,8 +450,8 @@
|
|||
"phpunit/phpunit": "^9.3"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-pcov": "*",
|
||||
"ext-xdebug": "*"
|
||||
"ext-pcov": "PHP extension that provides line coverage",
|
||||
"ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
|
@ -429,7 +484,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.23"
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.26"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -437,7 +492,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-12-28T12:41:10+00:00"
|
||||
"time": "2023-03-06T12:58:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
|
@ -682,20 +737,20 @@
|
|||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "9.5.27",
|
||||
"version": "9.6.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "a2bc7ffdca99f92d959b3f2270529334030bba38"
|
||||
"reference": "c993f0d3b0489ffc42ee2fe0bd645af1538a63b2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a2bc7ffdca99f92d959b3f2270529334030bba38",
|
||||
"reference": "a2bc7ffdca99f92d959b3f2270529334030bba38",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c993f0d3b0489ffc42ee2fe0bd645af1538a63b2",
|
||||
"reference": "c993f0d3b0489ffc42ee2fe0bd645af1538a63b2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/instantiator": "^1.3.1",
|
||||
"doctrine/instantiator": "^1.3.1 || ^2",
|
||||
"ext-dom": "*",
|
||||
"ext-json": "*",
|
||||
"ext-libxml": "*",
|
||||
|
@ -724,8 +779,8 @@
|
|||
"sebastian/version": "^3.0.2"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-soap": "*",
|
||||
"ext-xdebug": "*"
|
||||
"ext-soap": "To be able to generate mocks based on WSDL files",
|
||||
"ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
|
||||
},
|
||||
"bin": [
|
||||
"phpunit"
|
||||
|
@ -733,7 +788,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "9.5-dev"
|
||||
"dev-master": "9.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
@ -764,7 +819,8 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.27"
|
||||
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -780,7 +836,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-12-09T07:31:23+00:00"
|
||||
"time": "2023-04-14T08:58:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
|
@ -1148,16 +1204,16 @@
|
|||
},
|
||||
{
|
||||
"name": "sebastian/environment",
|
||||
"version": "5.1.4",
|
||||
"version": "5.1.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/environment.git",
|
||||
"reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7"
|
||||
"reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7",
|
||||
"reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
|
||||
"reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1199,7 +1255,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/environment/issues",
|
||||
"source": "https://github.com/sebastianbergmann/environment/tree/5.1.4"
|
||||
"source": "https://github.com/sebastianbergmann/environment/tree/5.1.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1207,7 +1263,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-04-03T09:37:03+00:00"
|
||||
"time": "2023-02-03T06:03:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/exporter",
|
||||
|
@ -1521,16 +1577,16 @@
|
|||
},
|
||||
{
|
||||
"name": "sebastian/recursion-context",
|
||||
"version": "4.0.4",
|
||||
"version": "4.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/recursion-context.git",
|
||||
"reference": "cd9d8cf3c5804de4341c283ed787f099f5506172"
|
||||
"reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172",
|
||||
"reference": "cd9d8cf3c5804de4341c283ed787f099f5506172",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
|
||||
"reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1569,10 +1625,10 @@
|
|||
}
|
||||
],
|
||||
"description": "Provides functionality to recursively process PHP variables",
|
||||
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
|
||||
"homepage": "https://github.com/sebastianbergmann/recursion-context",
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/recursion-context/issues",
|
||||
"source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4"
|
||||
"source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1580,7 +1636,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2020-10-26T13:17:30+00:00"
|
||||
"time": "2023-02-03T06:07:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/resource-operations",
|
||||
|
@ -1639,16 +1695,16 @@
|
|||
},
|
||||
{
|
||||
"name": "sebastian/type",
|
||||
"version": "3.2.0",
|
||||
"version": "3.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/type.git",
|
||||
"reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e"
|
||||
"reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e",
|
||||
"reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
|
||||
"reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1683,7 +1739,7 @@
|
|||
"homepage": "https://github.com/sebastianbergmann/type",
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/type/issues",
|
||||
"source": "https://github.com/sebastianbergmann/type/tree/3.2.0"
|
||||
"source": "https://github.com/sebastianbergmann/type/tree/3.2.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1691,7 +1747,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-09-12T14:47:03+00:00"
|
||||
"time": "2023-02-03T06:13:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/version",
|
||||
|
@ -1748,16 +1804,16 @@
|
|||
},
|
||||
{
|
||||
"name": "squizlabs/php_codesniffer",
|
||||
"version": "3.7.1",
|
||||
"version": "3.7.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
|
||||
"reference": "1359e176e9307e906dc3d890bcc9603ff6d90619"
|
||||
"reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619",
|
||||
"reference": "1359e176e9307e906dc3d890bcc9603ff6d90619",
|
||||
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879",
|
||||
"reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1793,14 +1849,15 @@
|
|||
"homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
|
||||
"keywords": [
|
||||
"phpcs",
|
||||
"standards"
|
||||
"standards",
|
||||
"static analysis"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
|
||||
"source": "https://github.com/squizlabs/PHP_CodeSniffer",
|
||||
"wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
|
||||
},
|
||||
"time": "2022-06-18T07:21:10+00:00"
|
||||
"time": "2023-02-22T23:07:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "theseer/tokenizer",
|
||||
|
@ -1867,9 +1924,11 @@
|
|||
"ext-gmp": "*",
|
||||
"ext-intl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-pdo": "*",
|
||||
"ext-pdo_sqlite": "*",
|
||||
"ext-session": "*",
|
||||
"ext-simplexml": "*",
|
||||
|
@ -1885,5 +1944,5 @@
|
|||
"ext-tokenizer": "*",
|
||||
"ext-xmlwriter": "*"
|
||||
},
|
||||
"plugin-api-version": "2.3.0"
|
||||
"plugin-api-version": "2.2.0"
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
/**
|
||||
* Manage configuration for the application.
|
||||
* @property-read string $base_url
|
||||
* @property array<string|array<int,string>> $db
|
||||
* @property array{'type'?:string,'host'?:string,'user'?:string,'password'?:string,'base'?:string,'prefix'?:string,
|
||||
* 'connection_uri_params'?:string,'pdo_options'?:array<string|int,string|int|bool>} $db
|
||||
* @property-read string $disable_update
|
||||
* @property-read string $environment
|
||||
* @property array<string,bool> $extensions_enabled
|
||||
|
@ -24,9 +25,10 @@ class Minz_Configuration {
|
|||
* @param string $namespace the name of the current configuration
|
||||
* @param string $config_filename the filename of the configuration
|
||||
* @param string $default_filename a filename containing default values for the configuration
|
||||
* @param object $configuration_setter an optional helper to set values in configuration
|
||||
* @param Minz_ConfigurationSetterInterface $configuration_setter an optional helper to set values in configuration
|
||||
*/
|
||||
public static function register(string $namespace, string $config_filename, string $default_filename = null, object $configuration_setter = null): void {
|
||||
public static function register(string $namespace, string $config_filename, string $default_filename = null,
|
||||
Minz_ConfigurationSetterInterface $configuration_setter = null): void {
|
||||
self::$config_list[$namespace] = new static(
|
||||
$namespace, $config_filename, $default_filename, $configuration_setter
|
||||
);
|
||||
|
@ -92,9 +94,9 @@ class Minz_Configuration {
|
|||
|
||||
/**
|
||||
* An object which help to set good values in configuration.
|
||||
* @var object|null
|
||||
* @var Minz_ConfigurationSetterInterface|null
|
||||
*/
|
||||
private $configuration_setter = null;
|
||||
private $configuration_setter;
|
||||
|
||||
/**
|
||||
* Create a new Minz_Configuration object.
|
||||
|
@ -102,9 +104,10 @@ class Minz_Configuration {
|
|||
* @param string $namespace the name of the current configuration.
|
||||
* @param string $config_filename the file containing configuration values.
|
||||
* @param string $default_filename the file containing default values, null by default.
|
||||
* @param object $configuration_setter an optional helper to set values in configuration
|
||||
* @param Minz_ConfigurationSetterInterface $configuration_setter an optional helper to set values in configuration
|
||||
*/
|
||||
private final function __construct(string $namespace, string $config_filename, string $default_filename = null, object $configuration_setter = null) {
|
||||
private final function __construct(string $namespace, string $config_filename, string $default_filename = null,
|
||||
Minz_ConfigurationSetterInterface $configuration_setter = null) {
|
||||
$this->namespace = $namespace;
|
||||
$this->config_filename = $config_filename;
|
||||
$this->default_filename = $default_filename;
|
||||
|
@ -127,16 +130,15 @@ class Minz_Configuration {
|
|||
|
||||
/**
|
||||
* Set a configuration setter for the current configuration.
|
||||
* @param object|null $configuration_setter the setter to call when modifying data. It
|
||||
* must implement an handle($key, $value) method.
|
||||
* @param Minz_ConfigurationSetterInterface|null $configuration_setter the setter to call when modifying data.
|
||||
*/
|
||||
public function _configurationSetter(?object $configuration_setter): void {
|
||||
public function _configurationSetter(?Minz_ConfigurationSetterInterface $configuration_setter): void {
|
||||
if (is_callable(array($configuration_setter, 'handle'))) {
|
||||
$this->configuration_setter = $configuration_setter;
|
||||
}
|
||||
}
|
||||
|
||||
public function configurationSetter(): object {
|
||||
public function configurationSetter(): ?Minz_ConfigurationSetterInterface {
|
||||
return $this->configuration_setter;
|
||||
}
|
||||
|
||||
|
@ -181,11 +183,11 @@ class Minz_Configuration {
|
|||
* @param mixed $value the value to set. If null, the key is removed from the configuration.
|
||||
*/
|
||||
public function _param(string $key, $value = null): void {
|
||||
if (!is_null($this->configuration_setter) && $this->configuration_setter->support($key)) {
|
||||
if ($this->configuration_setter !== null && $this->configuration_setter->support($key)) {
|
||||
$this->configuration_setter->handle($this->data, $key, $value);
|
||||
} elseif (isset($this->data[$key]) && is_null($value)) {
|
||||
unset($this->data[$key]);
|
||||
} elseif (!is_null($value)) {
|
||||
} elseif ($value !== null) {
|
||||
$this->data[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
interface Minz_ConfigurationSetterInterface {
|
||||
|
||||
/**
|
||||
* Return whether the given key is supported by this setter.
|
||||
* @param string $key the key to test.
|
||||
* @return bool true if the key is supported, false otherwise.
|
||||
*/
|
||||
public function support(string $key): bool;
|
||||
|
||||
/**
|
||||
* Set the given key in data with the current value.
|
||||
* @param array<string,mixed> $data an array containing the list of all configuration data.
|
||||
* @param string $key the key to update.
|
||||
* @param mixed $value the value to set.
|
||||
*/
|
||||
public function handle(&$data, string $key, $value): void;
|
||||
}
|
|
@ -87,19 +87,21 @@ class Minz_Dispatcher {
|
|||
$controller_name = 'FreshRSS_' . $base_name . '_Controller';
|
||||
}
|
||||
|
||||
if (!class_exists ($controller_name)) {
|
||||
if (!class_exists($controller_name)) {
|
||||
throw new Minz_ControllerNotExistException (
|
||||
Minz_Exception::ERROR
|
||||
);
|
||||
}
|
||||
$this->controller = new $controller_name ();
|
||||
$controller = new $controller_name();
|
||||
|
||||
if (! ($this->controller instanceof Minz_ActionController)) {
|
||||
if (!($controller instanceof Minz_ActionController)) {
|
||||
throw new Minz_ControllerNotActionControllerException (
|
||||
$controller_name,
|
||||
Minz_Exception::ERROR
|
||||
);
|
||||
}
|
||||
|
||||
$this->controller = $controller;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,20 +110,15 @@ class Minz_Dispatcher {
|
|||
* @throws Minz_ActionException if the action cannot be executed on the controller
|
||||
*/
|
||||
private function launchAction(string $action_name): void {
|
||||
if (!is_callable (array (
|
||||
$this->controller,
|
||||
$action_name
|
||||
))) {
|
||||
$call = [$this->controller, $action_name];
|
||||
if (!is_callable($call)) {
|
||||
throw new Minz_ActionException (
|
||||
get_class ($this->controller),
|
||||
get_class($this->controller),
|
||||
$action_name,
|
||||
Minz_Exception::ERROR
|
||||
);
|
||||
}
|
||||
call_user_func (array (
|
||||
$this->controller,
|
||||
$action_name
|
||||
));
|
||||
call_user_func($call);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -140,9 +137,9 @@ class Minz_Dispatcher {
|
|||
* Return if a controller is registered.
|
||||
*
|
||||
* @param string $base_name the base name of the controller.
|
||||
* @return boolean true if the controller has been registered, false else.
|
||||
* @return bool true if the controller has been registered, false else.
|
||||
*/
|
||||
public static function isRegistered(string $base_name) {
|
||||
public static function isRegistered(string $base_name): bool {
|
||||
return isset(self::$registrations[$base_name]);
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ class Minz_Error {
|
|||
* @param array<string,string>|string $logs logs sorted by category (error, warning, notice)
|
||||
* @return array<string> list of matching logs, without the category, according to environment preferences (production / development)
|
||||
*/
|
||||
private static function processLogs($logs) {
|
||||
private static function processLogs($logs): array {
|
||||
$conf = Minz_Configuration::get('system');
|
||||
$env = $conf->environment;
|
||||
$logs_ok = array ();
|
||||
|
|
|
@ -217,7 +217,7 @@ abstract class Minz_Extension {
|
|||
}
|
||||
|
||||
/** @param 'system'|'user' $type */
|
||||
private function isConfigurationEnabled($type): bool {
|
||||
private function isConfigurationEnabled(string $type): bool {
|
||||
if (!class_exists('FreshRSS_Context', false)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ abstract class Minz_Extension {
|
|||
}
|
||||
|
||||
/** @param 'system'|'user' $type */
|
||||
private function isExtensionConfigured($type): bool {
|
||||
private function isExtensionConfigured(string $type): bool {
|
||||
switch ($type) {
|
||||
case 'system':
|
||||
$conf = FreshRSS_Context::$user_conf;
|
||||
|
@ -248,7 +248,7 @@ abstract class Minz_Extension {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param 'system'|'user' $type
|
||||
* @phpstan-param 'system'|'user' $type
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
private function getConfiguration(string $type): array {
|
||||
|
@ -338,7 +338,7 @@ abstract class Minz_Extension {
|
|||
$this->user_configuration = $configuration;
|
||||
}
|
||||
|
||||
/** @param 'system'|'user' $type */
|
||||
/** @phpstan-param 'system'|'user' $type */
|
||||
private function removeConfiguration(string $type): void {
|
||||
if (!$this->isConfigurationEnabled($type)) {
|
||||
return;
|
||||
|
|
|
@ -364,7 +364,7 @@ final class Minz_ExtensionManager {
|
|||
foreach (self::$hook_list[$hook_name]['list'] as $function) {
|
||||
$result = call_user_func($function, $arg);
|
||||
|
||||
if (is_null($result)) {
|
||||
if ($result === null) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,11 +39,11 @@ class Minz_FrontController {
|
|||
Minz_Request::init();
|
||||
|
||||
$url = Minz_Url::build();
|
||||
$url['params'] = array_merge (
|
||||
$url['params'],
|
||||
$url['params'] = array_merge(
|
||||
empty($url['params']) || !is_array($url['params']) ? [] : $url['params'],
|
||||
$_POST
|
||||
);
|
||||
Minz_Request::forward ($url);
|
||||
Minz_Request::forward($url);
|
||||
} catch (Minz_Exception $e) {
|
||||
Minz_Log::error($e->getMessage());
|
||||
self::killApp($e->getMessage());
|
||||
|
|
|
@ -44,7 +44,7 @@ class Minz_Mailer {
|
|||
*/
|
||||
public function __construct () {
|
||||
$this->view = new Minz_View();
|
||||
$this->view->_layout(false);
|
||||
$this->view->_layout(null);
|
||||
$this->view->attributeParams();
|
||||
|
||||
$conf = Minz_Configuration::get('system');
|
||||
|
@ -66,10 +66,9 @@ class Minz_Mailer {
|
|||
*
|
||||
* @param string $to The recipient of the email
|
||||
* @param string $subject The subject of the email
|
||||
*
|
||||
* @return bool true on success, false if a SMTP error happens
|
||||
*/
|
||||
public function mail($to, $subject) {
|
||||
public function mail(string $to, string $subject): bool {
|
||||
ob_start();
|
||||
$this->view->render();
|
||||
$body = ob_get_contents();
|
||||
|
|
|
@ -38,11 +38,11 @@ class Minz_Migrator
|
|||
$applied_migrations = array_filter(explode("\n", $applied_migrations));
|
||||
|
||||
$migration_files = scandir($migrations_path);
|
||||
$migration_files = array_filter($migration_files, function ($filename) {
|
||||
$migration_files = array_filter($migration_files, static function (string $filename) {
|
||||
$file_extension = pathinfo($filename, PATHINFO_EXTENSION);
|
||||
return $file_extension === 'php';
|
||||
});
|
||||
$migration_versions = array_map(function ($filename) {
|
||||
$migration_versions = array_map(static function (string $filename) {
|
||||
return basename($filename, '.php');
|
||||
}, $migration_files);
|
||||
|
||||
|
@ -225,9 +225,8 @@ class Minz_Migrator
|
|||
}
|
||||
|
||||
/**
|
||||
* @return boolean Return true if the application is up-to-date, false
|
||||
* otherwise. If no migrations are registered, it always
|
||||
* returns true.
|
||||
* @return bool Return true if the application is up-to-date, false otherwise.
|
||||
* If no migrations are registered, it always returns true.
|
||||
*/
|
||||
public function upToDate(): bool {
|
||||
// Counting versions is enough since we cannot apply a version which
|
||||
|
|
|
@ -19,7 +19,7 @@ class Minz_ModelArray {
|
|||
* @param string $filename le nom du fichier à ouvrir contenant un tableau
|
||||
* Remarque : $array sera obligatoirement un tableau
|
||||
*/
|
||||
public function __construct ($filename) {
|
||||
public function __construct(string $filename) {
|
||||
$this->filename = $filename;
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ class Minz_ModelPdo {
|
|||
* @throws Minz_ConfigurationNamespaceException
|
||||
* @throws Minz_PDOConnectionException
|
||||
*/
|
||||
public function __construct($currentUser = null, $currentPdo = null) {
|
||||
public function __construct(?string $currentUser = null, ?Minz_Pdo $currentPdo = null) {
|
||||
if ($currentUser === null) {
|
||||
$currentUser = Minz_User::name();
|
||||
}
|
||||
|
|
|
@ -37,11 +37,11 @@ class Minz_Paginator {
|
|||
* Constructeur
|
||||
* @param array<Minz_Model> $items les éléments à gérer
|
||||
*/
|
||||
public function __construct ($items) {
|
||||
$this->_items ($items);
|
||||
$this->_nbItems (count ($this->items (true)));
|
||||
$this->_nbItemsPerPage ($this->nbItemsPerPage);
|
||||
$this->_currentPage ($this->currentPage);
|
||||
public function __construct(array $items) {
|
||||
$this->_items($items);
|
||||
$this->_nbItems(count($this->items(true)));
|
||||
$this->_nbItemsPerPage($this->nbItemsPerPage);
|
||||
$this->_currentPage($this->currentPage);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -49,25 +49,25 @@ class Minz_Paginator {
|
|||
* @param string $view nom du fichier de vue situé dans /app/views/helpers/
|
||||
* @param int $getteur variable de type $_GET[] permettant de retrouver la page
|
||||
*/
|
||||
public function render ($view, $getteur) {
|
||||
public function render(string $view, int $getteur = 0): void {
|
||||
$view = APP_PATH . '/views/helpers/' . $view;
|
||||
|
||||
if (file_exists ($view)) {
|
||||
include ($view);
|
||||
if (file_exists($view)) {
|
||||
include($view);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Permet de retrouver la page d'un élément donné
|
||||
* @param Minz_Model $item l'élément à retrouver
|
||||
* @return float|false la page à laquelle se trouve l’élément, false si non trouvé
|
||||
* @return int|false la page à laquelle se trouve l’élément, false si non trouvé
|
||||
*/
|
||||
public function pageByItem ($item) {
|
||||
public function pageByItem($item) {
|
||||
$i = 0;
|
||||
|
||||
do {
|
||||
if ($item == $this->items[$i]) {
|
||||
return ceil(($i + 1) / $this->nbItemsPerPage);
|
||||
return (int)(ceil(($i + 1) / $this->nbItemsPerPage));
|
||||
}
|
||||
$i++;
|
||||
} while ($i < $this->nbItems());
|
||||
|
@ -80,7 +80,7 @@ class Minz_Paginator {
|
|||
* @param Minz_Model $item the element to search
|
||||
* @return int|false the position of the element, or false if not found
|
||||
*/
|
||||
public function positionByItem ($item) {
|
||||
public function positionByItem($item) {
|
||||
$i = 0;
|
||||
|
||||
do {
|
||||
|
@ -96,9 +96,9 @@ class Minz_Paginator {
|
|||
/**
|
||||
* Permet de récupérer un item par sa position
|
||||
* @param int $pos la position de l'élément
|
||||
* @return mixed item situé à $pos (dernier item si $pos<0, 1er si $pos>=count($items))
|
||||
* @return Minz_Model item situé à $pos (dernier item si $pos<0, 1er si $pos>=count($items))
|
||||
*/
|
||||
public function itemByPosition ($pos) {
|
||||
public function itemByPosition(int $pos): Minz_Model {
|
||||
if ($pos < 0) {
|
||||
$pos = $this->nbItems () - 1;
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ class Minz_Paginator {
|
|||
* @param bool $all si à true, retourne tous les éléments sans prendre en compte la pagination
|
||||
* @return array<Minz_Model>
|
||||
*/
|
||||
public function items ($all = false) {
|
||||
public function items(bool $all = false): array {
|
||||
$array = array ();
|
||||
$nbItems = $this->nbItems ();
|
||||
|
||||
|
@ -141,30 +141,28 @@ class Minz_Paginator {
|
|||
|
||||
return $array;
|
||||
}
|
||||
public function nbItemsPerPage () {
|
||||
public function nbItemsPerPage(): int {
|
||||
return $this->nbItemsPerPage;
|
||||
}
|
||||
public function currentPage () {
|
||||
public function currentPage(): int {
|
||||
return $this->currentPage;
|
||||
}
|
||||
public function nbPage () {
|
||||
public function nbPage(): int {
|
||||
return $this->nbPage;
|
||||
}
|
||||
public function nbItems () {
|
||||
public function nbItems(): int {
|
||||
return $this->nbItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* SETTEURS
|
||||
*/
|
||||
public function _items ($items) {
|
||||
if (is_array ($items)) {
|
||||
$this->items = $items;
|
||||
}
|
||||
|
||||
$this->_nbPage ();
|
||||
/** @param array<Minz_Model> $items */
|
||||
public function _items(?array $items): void {
|
||||
$this->items = $items ?? [];
|
||||
$this->_nbPage();
|
||||
}
|
||||
public function _nbItemsPerPage ($nbItemsPerPage) {
|
||||
public function _nbItemsPerPage(int $nbItemsPerPage): void {
|
||||
if ($nbItemsPerPage > $this->nbItems ()) {
|
||||
$nbItemsPerPage = $this->nbItems ();
|
||||
}
|
||||
|
@ -173,21 +171,21 @@ class Minz_Paginator {
|
|||
}
|
||||
|
||||
$this->nbItemsPerPage = $nbItemsPerPage;
|
||||
$this->_nbPage ();
|
||||
$this->_nbPage();
|
||||
}
|
||||
public function _currentPage ($page) {
|
||||
public function _currentPage(int $page): void {
|
||||
if ($page < 1 || ($page > $this->nbPage && $this->nbPage > 0)) {
|
||||
throw new Minz_CurrentPagePaginationException($page);
|
||||
}
|
||||
|
||||
$this->currentPage = $page;
|
||||
}
|
||||
private function _nbPage () {
|
||||
private function _nbPage(): void {
|
||||
if ($this->nbItemsPerPage > 0) {
|
||||
$this->nbPage = (int)ceil($this->nbItems() / $this->nbItemsPerPage);
|
||||
}
|
||||
}
|
||||
public function _nbItems ($value) {
|
||||
public function _nbItems(int $value): void {
|
||||
$this->nbItems = $value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -298,7 +298,7 @@ class Minz_Request {
|
|||
* localhost address.
|
||||
*
|
||||
* @param string $address the address to test, can be an IP or a URL.
|
||||
* @return boolean true if server is accessible, false otherwise.
|
||||
* @return bool true if server is accessible, false otherwise.
|
||||
* @todo improve test with a more valid technique (e.g. test with an external server?)
|
||||
*/
|
||||
public static function serverIsPublic(string $address): bool {
|
||||
|
@ -360,7 +360,7 @@ class Minz_Request {
|
|||
$requests = Minz_Session::param('requests');
|
||||
if ($requests) {
|
||||
//Delete abandoned notifications
|
||||
$requests = array_filter($requests, function ($r) { return isset($r['time']) && $r['time'] > time() - 3600; });
|
||||
$requests = array_filter($requests, static function (array $r) { return isset($r['time']) && $r['time'] > time() - 3600; });
|
||||
|
||||
$requestId = self::requestId();
|
||||
if (!empty($requests[$requestId]['notification'])) {
|
||||
|
|
|
@ -133,8 +133,8 @@ class Minz_Translate {
|
|||
}
|
||||
|
||||
$list_i18n_files = array_values(array_diff(
|
||||
scandir($lang_path),
|
||||
array('..', '.')
|
||||
scandir($lang_path) ?: [],
|
||||
['..', '.']
|
||||
));
|
||||
|
||||
// Each file basename correspond to a top-level i18n key. For each of
|
||||
|
@ -199,8 +199,7 @@ class Minz_Translate {
|
|||
|
||||
// If $translates[$top_level] is null it means we have to load the
|
||||
// corresponding files.
|
||||
if (!isset(self::$translates[$top_level]) ||
|
||||
is_null(self::$translates[$top_level])) {
|
||||
if (empty(self::$translates[$top_level])) {
|
||||
$res = self::loadKey($top_level);
|
||||
if (!$res) {
|
||||
return $key;
|
||||
|
|
|
@ -60,7 +60,7 @@ class Minz_Url {
|
|||
* @param string $encodage pour indiquer comment encoder les & (& ou & pour html)
|
||||
* @return string uri sous la forme ?key=value&key2=value2
|
||||
*/
|
||||
private static function printUri($url, string $encodage): string {
|
||||
private static function printUri(array $url, string $encodage): string {
|
||||
$uri = '';
|
||||
$separator = '?';
|
||||
$anchor = '';
|
||||
|
@ -108,23 +108,15 @@ class Minz_Url {
|
|||
|
||||
/**
|
||||
* Check that all array elements representing the controller URL are OK
|
||||
* @param array<string,array<string,string>> $url controller URL as array
|
||||
* @param array<string,string|array<string,mixed>> $url controller URL as array
|
||||
* @return array{'c':string,'a':string,'params':array<string,mixed>} Verified controller URL as array
|
||||
*/
|
||||
public static function checkControllerUrl(array $url) {
|
||||
$url_checked = $url;
|
||||
|
||||
if (empty($url['c'])) {
|
||||
$url_checked['c'] = Minz_Request::defaultControllerName();
|
||||
}
|
||||
if (empty($url['a'])) {
|
||||
$url_checked['a'] = Minz_Request::defaultActionName();
|
||||
}
|
||||
if (empty($url['params'])) {
|
||||
$url_checked['params'] = [];
|
||||
}
|
||||
|
||||
return $url_checked;
|
||||
public static function checkControllerUrl(array $url): array {
|
||||
return [
|
||||
'c' => empty($url['c']) || !is_string($url['c']) ? Minz_Request::defaultControllerName() : $url['c'],
|
||||
'a' => empty($url['a']) || !is_string($url['a']) ? Minz_Request::defaultActionName() : $url['a'],
|
||||
'params' => empty($url['params']) || !is_array($url['params']) ? [] : $url['params'],
|
||||
];
|
||||
}
|
||||
|
||||
/** @param array<string,string|array<string,string>>|null $url */
|
||||
|
@ -139,7 +131,10 @@ class Minz_Url {
|
|||
}
|
||||
}
|
||||
|
||||
/** @return array<string,string|array<string,string>> */
|
||||
/**
|
||||
* @phpstan-return array{'c'?:string,'a'?:string,'params'?:array<string,mixed>}
|
||||
* @return array<string,string|array<string,string>>
|
||||
*/
|
||||
public static function unserialize(string $url = ''): array {
|
||||
try {
|
||||
return json_decode(base64_decode($url), true, JSON_THROW_ON_ERROR) ?? [];
|
||||
|
@ -150,7 +145,7 @@ class Minz_Url {
|
|||
|
||||
/**
|
||||
* Returns an array representing the URL as passed in the address bar
|
||||
* @return array<string,string|array<string,string>> URL representation
|
||||
* @return array{'c'?:string,'a'?:string,'params'?:array<string,mixed>} URL representation
|
||||
*/
|
||||
public static function build(): array {
|
||||
$url = [
|
||||
|
|
|
@ -22,7 +22,7 @@ class Minz_View {
|
|||
private static $title = '';
|
||||
/** @var array<array{'media':string,'url':string}> */
|
||||
private static $styles = [];
|
||||
/** @var array<array{'url':string,'id':string,'defer':string,'async':string}> */
|
||||
/** @var array<array{'url':string,'id':string,'defer':bool,'async':bool}> */
|
||||
private static $scripts = [];
|
||||
/** @var string|array{'dark'?:string,'light'?:string,'default'?:string} */
|
||||
private static $themeColors;
|
||||
|
@ -83,7 +83,7 @@ class Minz_View {
|
|||
* The file is searched inside list of $base_pathnames.
|
||||
*
|
||||
* @param string $filename the name of the file to include.
|
||||
* @return boolean true if the file has been included, false else.
|
||||
* @return bool true if the file has been included, false else.
|
||||
*/
|
||||
private function includeFile(string $filename): bool {
|
||||
// We search the filename in the list of base pathnames. Only the first view
|
||||
|
@ -158,9 +158,9 @@ class Minz_View {
|
|||
|
||||
/**
|
||||
* Choose the current view layout.
|
||||
* @param string|false $layout the layout name to use, false to use no layouts.
|
||||
* @param string|null $layout the layout name to use, false to use no layouts.
|
||||
*/
|
||||
public function _layout($layout): void {
|
||||
public function _layout(?string $layout): void {
|
||||
if ($layout) {
|
||||
$this->layout_filename = self::LAYOUT_PATH_NAME . $layout . '.phtml';
|
||||
} else {
|
||||
|
@ -178,7 +178,7 @@ class Minz_View {
|
|||
if ($use) {
|
||||
$this->_layout(self::LAYOUT_DEFAULT);
|
||||
} else {
|
||||
$this->_layout(false);
|
||||
$this->_layout(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,7 +326,6 @@ class Minz_View {
|
|||
|
||||
/**
|
||||
* Management of parameters added to the view
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public static function _param(string $key, $value): void {
|
||||
|
|
|
@ -34,7 +34,7 @@ example('PT6M/');
|
|||
example('PT7S/');
|
||||
example('P1DT1H/');
|
||||
|
||||
function example($dateInterval) {
|
||||
function example(string $dateInterval) {
|
||||
$dateIntervalArray = parseDateInterval($dateInterval);
|
||||
echo $dateInterval, "\t=>\t",
|
||||
$dateIntervalArray[0] == null ? 'null' : @date('c', $dateIntervalArray[0]), '/',
|
||||
|
@ -84,7 +84,7 @@ function _dateRelative(?string $d1, ?string $d2): ?string {
|
|||
* @return array{int|null|false,int|null|false} an array with the minimum and maximum Unix timestamp of this interval,
|
||||
* or null if open interval, or false if error.
|
||||
*/
|
||||
function parseDateInterval(string $dateInterval) {
|
||||
function parseDateInterval(string $dateInterval): array {
|
||||
$dateInterval = trim($dateInterval);
|
||||
$dateInterval = str_replace('--', '/', $dateInterval);
|
||||
$dateInterval = strtoupper($dateInterval);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
Minz_Configuration::register('default_system', join_path(FRESHRSS_PATH, 'config.default.php'));
|
||||
Minz_Configuration::register('default_user', join_path(FRESHRSS_PATH, 'config-user.default.php'));
|
||||
FreshRSS_SystemConfiguration::register('default_system', join_path(FRESHRSS_PATH, 'config.default.php'));
|
||||
FreshRSS_UserConfiguration::register('default_user', join_path(FRESHRSS_PATH, 'config-user.default.php'));
|
||||
|
||||
/** @return array<string,string> */
|
||||
function checkRequirements(string $dbType = ''): array {
|
||||
|
@ -76,7 +76,7 @@ function checkRequirements(string $dbType = ''): array {
|
|||
}
|
||||
|
||||
function generateSalt(): string {
|
||||
return sha1(uniqid('' . mt_rand(), true).implode('', stat(__FILE__)));
|
||||
return sha1(uniqid('' . mt_rand(), true).implode('', stat(__FILE__) ?: []));
|
||||
}
|
||||
|
||||
function initDb(): string {
|
||||
|
@ -88,10 +88,14 @@ function initDb(): string {
|
|||
$db['pdo_options'][PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
|
||||
$conf->db = $db; //TODO: Remove this Minz limitation "Indirect modification of overloaded property"
|
||||
|
||||
if (empty($db['type'])) {
|
||||
$db['type'] = 'sqlite';
|
||||
}
|
||||
|
||||
//Attempt to auto-create database if it does not already exist
|
||||
if ($db['type'] !== 'sqlite') {
|
||||
Minz_ModelPdo::$usesSharedPdo = false;
|
||||
$dbBase = isset($db['base']) ? $db['base'] : '';
|
||||
$dbBase = $db['base'] ?? '';
|
||||
//For first connection, use default database for PostgreSQL, empty database for MySQL / MariaDB:
|
||||
$db['base'] = $db['type'] === 'pgsql' ? 'postgres' : '';
|
||||
$conf->db = $db;
|
||||
|
|
|
@ -132,11 +132,7 @@ function checkUrl(string $url, bool $fixScheme = true) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
function safe_ascii($text) {
|
||||
function safe_ascii(string $text): string {
|
||||
return filter_var($text, FILTER_DEFAULT, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH) ?: '';
|
||||
}
|
||||
|
||||
|
@ -154,12 +150,7 @@ if (function_exists('mb_convert_encoding')) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
* @param bool $extended
|
||||
* @return string
|
||||
*/
|
||||
function escapeToUnicodeAlternative($text, $extended = true) {
|
||||
function escapeToUnicodeAlternative(string $text, bool $extended = true): string {
|
||||
$text = htmlspecialchars_decode($text, ENT_QUOTES);
|
||||
|
||||
//Problematic characters
|
||||
|
@ -176,7 +167,8 @@ function escapeToUnicodeAlternative($text, $extended = true) {
|
|||
return trim(str_replace($problem, $replace, $text));
|
||||
}
|
||||
|
||||
function format_number(float $n, int $precision = 0): string {
|
||||
/** @param int|float $n */
|
||||
function format_number($n, int $precision = 0): string {
|
||||
// number_format does not seem to be Unicode-compatible
|
||||
return str_replace(' ', ' ', // Thin non-breaking space
|
||||
number_format($n, $precision, '.', ' ')
|
||||
|
@ -255,7 +247,7 @@ function sensitive_log($log) {
|
|||
/**
|
||||
* @param array<string,mixed> $attributes
|
||||
*/
|
||||
function customSimplePie($attributes = array()): SimplePie {
|
||||
function customSimplePie(array $attributes = array()): SimplePie {
|
||||
if (FreshRSS_Context::$system_conf === null) {
|
||||
throw new FreshRSS_Context_Exception('System configuration not initialised!');
|
||||
}
|
||||
|
@ -339,10 +331,8 @@ function customSimplePie($attributes = array()): SimplePie {
|
|||
return $simplePie;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $data
|
||||
*/
|
||||
function sanitizeHTML($data, string $base = '', ?int $maxLength = null): string {
|
||||
/** @param string $data */
|
||||
function sanitizeHTML(string $data, string $base = '', ?int $maxLength = null): string {
|
||||
if (!is_string($data) || ($maxLength !== null && $maxLength <= 0)) {
|
||||
return '';
|
||||
}
|
||||
|
@ -579,7 +569,7 @@ function listUsers(): array {
|
|||
* Return if the maximum number of registrations has been reached.
|
||||
* Note a max_registrations of 0 means there is no limit.
|
||||
*
|
||||
* @return boolean true if number of users >= max registrations, false else.
|
||||
* @return bool true if number of users >= max registrations, false else.
|
||||
*/
|
||||
function max_registrations_reached(): bool {
|
||||
if (FreshRSS_Context::$system_conf === null) {
|
||||
|
@ -601,13 +591,13 @@ function max_registrations_reached(): bool {
|
|||
* @param string $username the name of the user of which we want the configuration.
|
||||
* @return FreshRSS_UserConfiguration|null object, or null if the configuration cannot be loaded.
|
||||
*/
|
||||
function get_user_configuration(string $username) {
|
||||
function get_user_configuration(string $username): ?FreshRSS_UserConfiguration {
|
||||
if (!FreshRSS_user_Controller::checkUsername($username)) {
|
||||
return null;
|
||||
}
|
||||
$namespace = 'user_' . $username;
|
||||
try {
|
||||
Minz_Configuration::register($namespace,
|
||||
FreshRSS_UserConfiguration::register($namespace,
|
||||
USERS_PATH . '/' . $username . '/config.php',
|
||||
FRESHRSS_PATH . '/config-user.default.php');
|
||||
} catch (Minz_ConfigurationNamespaceException $e) {
|
||||
|
@ -618,10 +608,7 @@ function get_user_configuration(string $username) {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var FreshRSS_UserConfiguration $user_conf
|
||||
*/
|
||||
$user_conf = Minz_Configuration::get($namespace);
|
||||
$user_conf = FreshRSS_UserConfiguration::get($namespace);
|
||||
return $user_conf;
|
||||
}
|
||||
|
||||
|
@ -644,7 +631,7 @@ function ipToBits(string $ip): string {
|
|||
*
|
||||
* @param string $ip the IP that we want to verify (ex: 192.168.16.1)
|
||||
* @param string $range the range to check against (ex: 192.168.16.0/24)
|
||||
* @return boolean true if the IP is in the range, otherwise false
|
||||
* @return bool true if the IP is in the range, otherwise false
|
||||
*/
|
||||
function checkCIDR(string $ip, string $range): bool {
|
||||
$binary_ip = ipToBits($ip);
|
||||
|
@ -663,7 +650,7 @@ function checkCIDR(string $ip, string $range): bool {
|
|||
* This uses the REMOTE_ADDR header to determine the sender's IP
|
||||
* and the configuration option "trusted_sources" to get an array of the authorized ranges
|
||||
*
|
||||
* @return boolean, true if the sender's IP is in one of the ranges defined in the configuration, else false
|
||||
* @return bool, true if the sender's IP is in one of the ranges defined in the configuration, else false
|
||||
*/
|
||||
function checkTrustedIP(): bool {
|
||||
if (FreshRSS_Context::$system_conf === null) {
|
||||
|
@ -840,7 +827,7 @@ const SHORTCUT_KEYS = [
|
|||
function getNonStandardShortcuts(array $shortcuts): array {
|
||||
$standard = strtolower(implode(' ', SHORTCUT_KEYS));
|
||||
|
||||
$nonStandard = array_filter($shortcuts, function ($shortcut) use ($standard) {
|
||||
$nonStandard = array_filter($shortcuts, static function (string $shortcut) use ($standard) {
|
||||
$shortcut = trim($shortcut);
|
||||
return $shortcut !== '' & stripos($standard, $shortcut) === false;
|
||||
});
|
||||
|
|
|
@ -336,9 +336,8 @@ final class FeverAPI
|
|||
$groups = array();
|
||||
|
||||
$categoryDAO = FreshRSS_Factory::createCategoryDao();
|
||||
$categories = $categoryDAO->listCategories(false, false);
|
||||
$categories = $categoryDAO->listCategories(false, false) ?: [];
|
||||
|
||||
/** @var FreshRSS_Category $category */
|
||||
foreach ($categories as $category) {
|
||||
$groups[] = array(
|
||||
'id' => $category->id(),
|
||||
|
@ -430,28 +429,28 @@ final class FeverAPI
|
|||
}
|
||||
|
||||
/**
|
||||
* @return integer|false
|
||||
* @return int|false
|
||||
*/
|
||||
private function setItemAsRead(string $id) {
|
||||
return $this->entryDAO->markRead($id, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer|false
|
||||
* @return int|false
|
||||
*/
|
||||
private function setItemAsUnread(string $id) {
|
||||
return $this->entryDAO->markRead($id, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer|false
|
||||
* @return int|false
|
||||
*/
|
||||
private function setItemAsSaved(string $id) {
|
||||
return $this->entryDAO->markFavorite($id, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer|false
|
||||
* @return int|false
|
||||
*/
|
||||
private function setItemAsUnsaved(string $id) {
|
||||
return $this->entryDAO->markFavorite($id, false);
|
||||
|
@ -540,7 +539,7 @@ final class FeverAPI
|
|||
}
|
||||
|
||||
/**
|
||||
* @return integer|false
|
||||
* @return int|false
|
||||
*/
|
||||
private function setFeedAsRead(int $id, int $before) {
|
||||
$before = $this->convertBeforeToId($before);
|
||||
|
@ -548,7 +547,7 @@ final class FeverAPI
|
|||
}
|
||||
|
||||
/**
|
||||
* @return integer|false
|
||||
* @return int|false
|
||||
*/
|
||||
private function setGroupAsRead(int $id, int $before) {
|
||||
$before = $this->convertBeforeToId($before);
|
||||
|
|
6
p/f.php
6
p/f.php
|
@ -5,7 +5,7 @@ require(LIB_PATH . '/favicons.php');
|
|||
require(LIB_PATH . '/http-conditional.php');
|
||||
|
||||
function show_default_favicon(int $cacheSeconds = 3600): void {
|
||||
$default_mtime = @filemtime(DEFAULT_FAVICON);
|
||||
$default_mtime = @filemtime(DEFAULT_FAVICON) ?: 0;
|
||||
if (!httpConditional($default_mtime, $cacheSeconds, 2)) {
|
||||
header('Content-Type: image/x-icon');
|
||||
header('Content-Disposition: inline; filename="default_favicon.ico"');
|
||||
|
@ -21,8 +21,8 @@ if (!ctype_xdigit($id)) {
|
|||
$txt = FAVICONS_DIR . $id . '.txt';
|
||||
$ico = FAVICONS_DIR . $id . '.ico';
|
||||
|
||||
$ico_mtime = @filemtime($ico);
|
||||
$txt_mtime = @filemtime($txt);
|
||||
$ico_mtime = @filemtime($ico) ?: 0;
|
||||
$txt_mtime = @filemtime($txt) ?: 0;
|
||||
|
||||
if ($ico_mtime == false || $ico_mtime < $txt_mtime || ($ico_mtime < time() - (mt_rand(15, 20) * 86400))) {
|
||||
if ($txt_mtime == false) {
|
||||
|
|
|
@ -35,8 +35,8 @@ if (!file_exists($applied_migrations_path)) {
|
|||
require(LIB_PATH . '/http-conditional.php');
|
||||
$currentUser = Minz_User::name();
|
||||
$dateLastModification = $currentUser === null ? time() : max(
|
||||
@filemtime(USERS_PATH . '/' . $currentUser . '/' . LOG_FILENAME),
|
||||
@filemtime(DATA_PATH . '/config.php')
|
||||
@filemtime(USERS_PATH . '/' . $currentUser . '/' . LOG_FILENAME) ?: 0,
|
||||
@filemtime(DATA_PATH . '/config.php') ?: 0
|
||||
);
|
||||
if (httpConditional($dateLastModification, 0, 0, false, PHP_COMPRESSION, true)) {
|
||||
Minz_Session::init('FreshRSS');
|
||||
|
|
11
phpstan.neon
11
phpstan.neon
|
@ -1,6 +1,7 @@
|
|||
parameters:
|
||||
# TODO: Increase rule-level https://phpstan.org/user-guide/rule-levels
|
||||
level: 5
|
||||
level: 6
|
||||
treatPhpDocTypesAsCertain: false
|
||||
fileExtensions:
|
||||
- php
|
||||
- phtml
|
||||
|
@ -9,14 +10,16 @@ parameters:
|
|||
excludePaths:
|
||||
analyse:
|
||||
- lib/marienfressinaud/*
|
||||
- lib/phpgt/*
|
||||
- lib/phpmailer/*
|
||||
- lib/SimplePie/*
|
||||
- vendor/*
|
||||
analyseAndScan:
|
||||
- .git/*
|
||||
- node_modules/*
|
||||
# TODO: include tests
|
||||
- tests/*
|
||||
- vendor/*
|
||||
bootstrapFiles:
|
||||
- cli/_cli.php
|
||||
- lib/favicons.php
|
||||
includes:
|
||||
- vendor/phpstan/phpstan-phpunit/extension.neon
|
||||
- vendor/phpstan/phpstan-phpunit/rules.neon
|
||||
|
|
|
@ -2,23 +2,22 @@
|
|||
|
||||
class CategoryTest extends PHPUnit\Framework\TestCase {
|
||||
|
||||
public function test__construct_whenNoParameters_createsObjectWithDefaultValues() {
|
||||
public function test__construct_whenNoParameters_createsObjectWithDefaultValues(): void {
|
||||
$category = new FreshRSS_Category();
|
||||
$this->assertEquals(0, $category->id());
|
||||
$this->assertEquals('', $category->name());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $input
|
||||
* @param string $expected
|
||||
* @dataProvider provideValidNames
|
||||
*/
|
||||
public function test_name_whenValidValue_storesModifiedValue($input, $expected) {
|
||||
public function test_name_whenValidValue_storesModifiedValue(string $input, string $expected): void {
|
||||
$category = new FreshRSS_Category($input);
|
||||
$this->assertEquals($expected, $category->name());
|
||||
}
|
||||
|
||||
public function provideValidNames() {
|
||||
/** @return array<array{string,string}> */
|
||||
public function provideValidNames(): array {
|
||||
return array(
|
||||
array('', ''),
|
||||
array('this string does not need trimming', 'this string does not need trimming'),
|
||||
|
@ -30,7 +29,7 @@ class CategoryTest extends PHPUnit\Framework\TestCase {
|
|||
);
|
||||
}
|
||||
|
||||
public function test_feedOrdering() {
|
||||
public function test_feedOrdering(): void {
|
||||
$feed_1 = $this->getMockBuilder(FreshRSS_Feed::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
|
|
@ -36,7 +36,7 @@ class LogDAOTest extends TestCase {
|
|||
|
||||
$this->logDAO::truncate(self::LOG_FILE_TEST);
|
||||
|
||||
$this->assertStringContainsString('', file_get_contents($this->logPath));
|
||||
$this->assertStringContainsString('', file_get_contents($this->logPath) ?: '');
|
||||
}
|
||||
|
||||
protected function tearDown(): void {
|
||||
|
|
|
@ -6,9 +6,8 @@ class SearchTest extends PHPUnit\Framework\TestCase {
|
|||
|
||||
/**
|
||||
* @dataProvider provideEmptyInput
|
||||
* @param string|null $input
|
||||
*/
|
||||
public function test__construct_whenInputIsEmpty_getsOnlyNullValues($input) {
|
||||
public function test__construct_whenInputIsEmpty_getsOnlyNullValues(?string $input): void {
|
||||
$search = new FreshRSS_Search($input);
|
||||
$this->assertEquals('', $search->getRawInput());
|
||||
$this->assertNull($search->getIntitle());
|
||||
|
@ -24,9 +23,9 @@ class SearchTest extends PHPUnit\Framework\TestCase {
|
|||
/**
|
||||
* Return an array of values for the search object.
|
||||
* Here is the description of the values
|
||||
* @return array
|
||||
* @return array{array{''},array{null}}
|
||||
*/
|
||||
public function provideEmptyInput() {
|
||||
public function provideEmptyInput(): array {
|
||||
return array(
|
||||
array(''),
|
||||
array(null),
|
||||
|
@ -35,20 +34,19 @@ class SearchTest extends PHPUnit\Framework\TestCase {
|
|||
|
||||
/**
|
||||
* @dataProvider provideIntitleSearch
|
||||
* @param string $input
|
||||
* @param string $intitle_value
|
||||
* @param string|null $search_value
|
||||
* @param array<string>|null $intitle_value
|
||||
* @param array<string>|null $search_value
|
||||
*/
|
||||
public function test__construct_whenInputContainsIntitle_setsIntitleProperty($input, $intitle_value, $search_value) {
|
||||
public function test__construct_whenInputContainsIntitle_setsIntitleProperty(string $input, ?array $intitle_value, ?array $search_value): void {
|
||||
$search = new FreshRSS_Search($input);
|
||||
$this->assertEquals($intitle_value, $search->getIntitle());
|
||||
$this->assertEquals($search_value, $search->getSearch());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @return array<array<mixed>>
|
||||
*/
|
||||
public function provideIntitleSearch() {
|
||||
public function provideIntitleSearch(): array {
|
||||
return array(
|
||||
array('intitle:word1', array('word1'), null),
|
||||
array('intitle:word1-word2', array('word1-word2'), null),
|
||||
|
@ -73,20 +71,19 @@ class SearchTest extends PHPUnit\Framework\TestCase {
|
|||
|
||||
/**
|
||||
* @dataProvider provideAuthorSearch
|
||||
* @param string $input
|
||||
* @param string $author_value
|
||||
* @param string|null $search_value
|
||||
* @param array<string>|null $author_value
|
||||
* @param array<string>|null $search_value
|
||||
*/
|
||||
public function test__construct_whenInputContainsAuthor_setsAuthorValue($input, $author_value, $search_value) {
|
||||
public function test__construct_whenInputContainsAuthor_setsAuthorValue(string $input, ?array $author_value, ?array $search_value): void {
|
||||
$search = new FreshRSS_Search($input);
|
||||
$this->assertEquals($author_value, $search->getAuthor());
|
||||
$this->assertEquals($search_value, $search->getSearch());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @return array<array<mixed>>
|
||||
*/
|
||||
public function provideAuthorSearch() {
|
||||
public function provideAuthorSearch(): array {
|
||||
return array(
|
||||
array('author:word1', array('word1'), null),
|
||||
array('author:word1-word2', array('word1-word2'), null),
|
||||
|
@ -111,20 +108,19 @@ class SearchTest extends PHPUnit\Framework\TestCase {
|
|||
|
||||
/**
|
||||
* @dataProvider provideInurlSearch
|
||||
* @param string $input
|
||||
* @param string $inurl_value
|
||||
* @param string|null $search_value
|
||||
* @param array<string>|null $inurl_value
|
||||
* @param array<string>|null $search_value
|
||||
*/
|
||||
public function test__construct_whenInputContainsInurl_setsInurlValue($input, $inurl_value, $search_value) {
|
||||
public function test__construct_whenInputContainsInurl_setsInurlValue(string $input, ?array $inurl_value, ?array $search_value): void {
|
||||
$search = new FreshRSS_Search($input);
|
||||
$this->assertEquals($inurl_value, $search->getInurl());
|
||||
$this->assertEquals($search_value, $search->getSearch());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @return array<array<mixed>>
|
||||
*/
|
||||
public function provideInurlSearch() {
|
||||
public function provideInurlSearch(): array {
|
||||
return array(
|
||||
array('inurl:word1', array('word1'), null),
|
||||
array('inurl: word1', array(), array('word1')),
|
||||
|
@ -139,72 +135,65 @@ class SearchTest extends PHPUnit\Framework\TestCase {
|
|||
|
||||
/**
|
||||
* @dataProvider provideDateSearch
|
||||
* @param string $input
|
||||
* @param string $min_date_value
|
||||
* @param string $max_date_value
|
||||
*/
|
||||
public function test__construct_whenInputContainsDate_setsDateValues($input, $min_date_value, $max_date_value) {
|
||||
public function test__construct_whenInputContainsDate_setsDateValues(string $input, ?int $min_date_value, ?int $max_date_value): void {
|
||||
$search = new FreshRSS_Search($input);
|
||||
$this->assertEquals($min_date_value, $search->getMinDate());
|
||||
$this->assertEquals($max_date_value, $search->getMaxDate());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @return array<array<mixed>>
|
||||
*/
|
||||
public function provideDateSearch() {
|
||||
public function provideDateSearch(): array {
|
||||
return array(
|
||||
array('date:2007-03-01T13:00:00Z/2008-05-11T15:30:00Z', '1172754000', '1210519800'),
|
||||
array('date:2007-03-01T13:00:00Z/P1Y2M10DT2H30M', '1172754000', '1210519799'),
|
||||
array('date:P1Y2M10DT2H30M/2008-05-11T15:30:00Z', '1172754001', '1210519800'),
|
||||
array('date:2007-03-01T13:00:00Z/2008-05-11T15:30:00Z', 1172754000, 1210519800),
|
||||
array('date:2007-03-01T13:00:00Z/P1Y2M10DT2H30M', 1172754000, 1210519799),
|
||||
array('date:P1Y2M10DT2H30M/2008-05-11T15:30:00Z', 1172754001, 1210519800),
|
||||
array('date:2007-03-01/2008-05-11', strtotime('2007-03-01'), strtotime('2008-05-12') - 1),
|
||||
array('date:2007-03-01/', strtotime('2007-03-01'), ''),
|
||||
array('date:/2008-05-11', '', strtotime('2008-05-12') - 1),
|
||||
array('date:2007-03-01/', strtotime('2007-03-01'), null),
|
||||
array('date:/2008-05-11', null, strtotime('2008-05-12') - 1),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providePubdateSearch
|
||||
* @param string $input
|
||||
* @param string $min_pubdate_value
|
||||
* @param string $max_pubdate_value
|
||||
*/
|
||||
public function test__construct_whenInputContainsPubdate_setsPubdateValues($input, $min_pubdate_value, $max_pubdate_value) {
|
||||
public function test__construct_whenInputContainsPubdate_setsPubdateValues(string $input, ?int $min_pubdate_value, ?int $max_pubdate_value): void {
|
||||
$search = new FreshRSS_Search($input);
|
||||
$this->assertEquals($min_pubdate_value, $search->getMinPubdate());
|
||||
$this->assertEquals($max_pubdate_value, $search->getMaxPubdate());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @return array<array<mixed>>
|
||||
*/
|
||||
public function providePubdateSearch() {
|
||||
public function providePubdateSearch(): array {
|
||||
return array(
|
||||
array('pubdate:2007-03-01T13:00:00Z/2008-05-11T15:30:00Z', '1172754000', '1210519800'),
|
||||
array('pubdate:2007-03-01T13:00:00Z/P1Y2M10DT2H30M', '1172754000', '1210519799'),
|
||||
array('pubdate:P1Y2M10DT2H30M/2008-05-11T15:30:00Z', '1172754001', '1210519800'),
|
||||
array('pubdate:2007-03-01T13:00:00Z/2008-05-11T15:30:00Z', 1172754000, 1210519800),
|
||||
array('pubdate:2007-03-01T13:00:00Z/P1Y2M10DT2H30M', 1172754000, 1210519799),
|
||||
array('pubdate:P1Y2M10DT2H30M/2008-05-11T15:30:00Z', 1172754001, 1210519800),
|
||||
array('pubdate:2007-03-01/2008-05-11', strtotime('2007-03-01'), strtotime('2008-05-12') - 1),
|
||||
array('pubdate:2007-03-01/', strtotime('2007-03-01'), ''),
|
||||
array('pubdate:/2008-05-11', '', strtotime('2008-05-12') - 1),
|
||||
array('pubdate:2007-03-01/', strtotime('2007-03-01'), null),
|
||||
array('pubdate:/2008-05-11', null, strtotime('2008-05-12') - 1),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTagsSearch
|
||||
* @param string $input
|
||||
* @param string $tags_value
|
||||
* @param string|null $search_value
|
||||
* @param array<string>|null $tags_value
|
||||
* @param array<string>|null $search_value
|
||||
*/
|
||||
public function test__construct_whenInputContainsTags_setsTagsValue($input, $tags_value, $search_value) {
|
||||
public function test__construct_whenInputContainsTags_setsTagsValue(string $input, ?array $tags_value, ?array $search_value): void {
|
||||
$search = new FreshRSS_Search($input);
|
||||
$this->assertEquals($tags_value, $search->getTags());
|
||||
$this->assertEquals($search_value, $search->getSearch());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @return array<array<string|array<string>|null>>
|
||||
*/
|
||||
public function provideTagsSearch() {
|
||||
public function provideTagsSearch(): array {
|
||||
return array(
|
||||
array('#word1', array('word1'), null),
|
||||
array('# word1', array(), array('#', 'word1')),
|
||||
|
@ -219,19 +208,15 @@ class SearchTest extends PHPUnit\Framework\TestCase {
|
|||
|
||||
/**
|
||||
* @dataProvider provideMultipleSearch
|
||||
* @param string $input
|
||||
* @param string $author_value
|
||||
* @param string $min_date_value
|
||||
* @param string $max_date_value
|
||||
* @param string $intitle_value
|
||||
* @param string $inurl_value
|
||||
* @param string $min_pubdate_value
|
||||
* @param string $max_pubdate_value
|
||||
* @param array $tags_value
|
||||
* @param string|null $search_value
|
||||
* @param array<string>|null $author_value
|
||||
* @param array<string> $intitle_value
|
||||
* @param array<string>|null $inurl_value
|
||||
* @param array<string>|null $tags_value
|
||||
* @param array<string>|null $search_value
|
||||
*/
|
||||
public function test__construct_whenInputContainsMultipleKeywords_setsValues($input, $author_value, $min_date_value,
|
||||
$max_date_value, $intitle_value, $inurl_value, $min_pubdate_value, $max_pubdate_value, $tags_value, $search_value) {
|
||||
public function test__construct_whenInputContainsMultipleKeywords_setsValues(string $input, ?array $author_value, ?int $min_date_value,
|
||||
?int $max_date_value, ?array $intitle_value, ?array $inurl_value, ?int $min_pubdate_value,
|
||||
?int $max_pubdate_value, ?array $tags_value, ?array $search_value): void {
|
||||
$search = new FreshRSS_Search($input);
|
||||
$this->assertEquals($author_value, $search->getAuthor());
|
||||
$this->assertEquals($min_date_value, $search->getMinDate());
|
||||
|
@ -245,7 +230,8 @@ class SearchTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals($input, $search->getRawInput());
|
||||
}
|
||||
|
||||
public function provideMultipleSearch() {
|
||||
/** @return array<array<mixed>> */
|
||||
public function provideMultipleSearch(): array {
|
||||
return array(
|
||||
array(
|
||||
'author:word1 date:2007-03-01/2008-05-11 intitle:word2 inurl:word3 pubdate:2007-03-01/2008-05-11 #word4 #word5',
|
||||
|
@ -302,13 +288,14 @@ class SearchTest extends PHPUnit\Framework\TestCase {
|
|||
* @dataProvider provideParentheses
|
||||
* @param array<string> $values
|
||||
*/
|
||||
public function test__construct_parentheses(string $input, string $sql, $values) {
|
||||
public function test__construct_parentheses(string $input, string $sql, array $values): void {
|
||||
list($filterValues, $filterSearch) = FreshRSS_EntryDAOPGSQL::sqlBooleanSearch('e.', new FreshRSS_BooleanSearch($input));
|
||||
$this->assertEquals($sql, $filterSearch);
|
||||
$this->assertEquals($values, $filterValues);
|
||||
}
|
||||
|
||||
public function provideParentheses() {
|
||||
/** @return array<array<mixed>> */
|
||||
public function provideParentheses(): array {
|
||||
return [
|
||||
[
|
||||
'f:1 (f:2 OR f:3 OR f:4) (f:5 OR (f:6 OR f:7))',
|
||||
|
|
|
@ -5,21 +5,21 @@
|
|||
*/
|
||||
class UserQueryTest extends PHPUnit\Framework\TestCase {
|
||||
|
||||
public function test__construct_whenAllQuery_storesAllParameters() {
|
||||
public function test__construct_whenAllQuery_storesAllParameters(): void {
|
||||
$query = array('get' => 'a');
|
||||
$user_query = new FreshRSS_UserQuery($query);
|
||||
$this->assertEquals('all', $user_query->getGetName());
|
||||
$this->assertEquals('all', $user_query->getGetType());
|
||||
}
|
||||
|
||||
public function test__construct_whenFavoriteQuery_storesFavoriteParameters() {
|
||||
public function test__construct_whenFavoriteQuery_storesFavoriteParameters(): void {
|
||||
$query = array('get' => 's');
|
||||
$user_query = new FreshRSS_UserQuery($query);
|
||||
$this->assertEquals('favorite', $user_query->getGetName());
|
||||
$this->assertEquals('favorite', $user_query->getGetType());
|
||||
}
|
||||
|
||||
public function test__construct_whenCategoryQueryAndNoDao_throwsException() {
|
||||
public function test__construct_whenCategoryQueryAndNoDao_throwsException(): void {
|
||||
$this->expectException(FreshRSS_DAO_Exception::class);
|
||||
$this->expectExceptionMessage('Category DAO is not loaded in UserQuery');
|
||||
|
||||
|
@ -27,13 +27,15 @@ class UserQueryTest extends PHPUnit\Framework\TestCase {
|
|||
new FreshRSS_UserQuery($query);
|
||||
}
|
||||
|
||||
public function test__construct_whenCategoryQuery_storesCategoryParameters() {
|
||||
public function test__construct_whenCategoryQuery_storesCategoryParameters(): void {
|
||||
$category_name = 'some category name';
|
||||
/** @var FreshRSS_Category&PHPUnit\Framework\MockObject\MockObject */
|
||||
$cat = $this->createMock('FreshRSS_Category');
|
||||
$cat->expects($this->atLeastOnce())
|
||||
->method('name')
|
||||
->withAnyParameters()
|
||||
->willReturn($category_name);
|
||||
/** @var FreshRSS_CategoryDAO&PHPUnit\Framework\MockObject\MockObject */
|
||||
$cat_dao = $this->createMock('FreshRSS_CategoryDAO');
|
||||
$cat_dao->expects($this->atLeastOnce())
|
||||
->method('searchById')
|
||||
|
@ -45,7 +47,7 @@ class UserQueryTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals('category', $user_query->getGetType());
|
||||
}
|
||||
|
||||
public function test__construct_whenFeedQueryAndNoDao_throwsException() {
|
||||
public function test__construct_whenFeedQueryAndNoDao_throwsException(): void {
|
||||
$this->expectException(FreshRSS_DAO_Exception::class);
|
||||
$this->expectExceptionMessage('Feed DAO is not loaded in UserQuery');
|
||||
|
||||
|
@ -53,13 +55,15 @@ class UserQueryTest extends PHPUnit\Framework\TestCase {
|
|||
new FreshRSS_UserQuery($query);
|
||||
}
|
||||
|
||||
public function test__construct_whenFeedQuery_storesFeedParameters() {
|
||||
public function test__construct_whenFeedQuery_storesFeedParameters(): void {
|
||||
$feed_name = 'some feed name';
|
||||
$feed = $this->createMock('FreshRSS_Feed', array(), array('', false));
|
||||
/** @var FreshRSS_Feed&PHPUnit\Framework\MockObject\MockObject */
|
||||
$feed = $this->createMock('FreshRSS_Feed');
|
||||
$feed->expects($this->atLeastOnce())
|
||||
->method('name')
|
||||
->withAnyParameters()
|
||||
->willReturn($feed_name);
|
||||
/** @var FreshRSS_FeedDAO&PHPUnit\Framework\MockObject\MockObject */
|
||||
$feed_dao = $this->createMock('FreshRSS_FeedDAO');
|
||||
$feed_dao->expects($this->atLeastOnce())
|
||||
->method('searchById')
|
||||
|
@ -71,48 +75,48 @@ class UserQueryTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals('feed', $user_query->getGetType());
|
||||
}
|
||||
|
||||
public function test__construct_whenUnknownQuery_doesStoreParameters() {
|
||||
public function test__construct_whenUnknownQuery_doesStoreParameters(): void {
|
||||
$query = array('get' => 'q');
|
||||
$user_query = new FreshRSS_UserQuery($query);
|
||||
$this->assertEmpty($user_query->getGetName());
|
||||
$this->assertEmpty($user_query->getGetType());
|
||||
}
|
||||
|
||||
public function test__construct_whenName_storesName() {
|
||||
public function test__construct_whenName_storesName(): void {
|
||||
$name = 'some name';
|
||||
$query = array('name' => $name);
|
||||
$user_query = new FreshRSS_UserQuery($query);
|
||||
$this->assertEquals($name, $user_query->getName());
|
||||
}
|
||||
|
||||
public function test__construct_whenOrder_storesOrder() {
|
||||
public function test__construct_whenOrder_storesOrder(): void {
|
||||
$order = 'some order';
|
||||
$query = array('order' => $order);
|
||||
$user_query = new FreshRSS_UserQuery($query);
|
||||
$this->assertEquals($order, $user_query->getOrder());
|
||||
}
|
||||
|
||||
public function test__construct_whenState_storesState() {
|
||||
public function test__construct_whenState_storesState(): void {
|
||||
$state = FreshRSS_Entry::STATE_ALL;
|
||||
$query = array('state' => $state);
|
||||
$user_query = new FreshRSS_UserQuery($query);
|
||||
$this->assertEquals($state, $user_query->getState());
|
||||
}
|
||||
|
||||
public function test__construct_whenUrl_storesUrl() {
|
||||
public function test__construct_whenUrl_storesUrl(): void {
|
||||
$url = 'some url';
|
||||
$query = array('url' => $url);
|
||||
$user_query = new FreshRSS_UserQuery($query);
|
||||
$this->assertEquals($url, $user_query->getUrl());
|
||||
}
|
||||
|
||||
public function testToArray_whenNoData_returnsEmptyArray() {
|
||||
public function testToArray_whenNoData_returnsEmptyArray(): void {
|
||||
$user_query = new FreshRSS_UserQuery(array());
|
||||
$this->assertIsIterable($user_query->toArray());
|
||||
$this->assertCount(0, $user_query->toArray());
|
||||
}
|
||||
|
||||
public function testToArray_whenData_returnsArray() {
|
||||
public function testToArray_whenData_returnsArray(): void {
|
||||
$query = array(
|
||||
'get' => 's',
|
||||
'name' => 'some name',
|
||||
|
@ -127,7 +131,7 @@ class UserQueryTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals($query, $user_query->toArray());
|
||||
}
|
||||
|
||||
public function testHasSearch_whenSearch_returnsTrue() {
|
||||
public function testHasSearch_whenSearch_returnsTrue(): void {
|
||||
$query = array(
|
||||
'search' => 'some search',
|
||||
);
|
||||
|
@ -135,31 +139,33 @@ class UserQueryTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertTrue($user_query->hasSearch());
|
||||
}
|
||||
|
||||
public function testHasSearch_whenNoSearch_returnsFalse() {
|
||||
public function testHasSearch_whenNoSearch_returnsFalse(): void {
|
||||
$user_query = new FreshRSS_UserQuery(array());
|
||||
$this->assertFalse($user_query->hasSearch());
|
||||
}
|
||||
|
||||
public function testHasParameters_whenAllQuery_returnsFalse() {
|
||||
public function testHasParameters_whenAllQuery_returnsFalse(): void {
|
||||
$query = array('get' => 'a');
|
||||
$user_query = new FreshRSS_UserQuery($query);
|
||||
$this->assertFalse($user_query->hasParameters());
|
||||
}
|
||||
|
||||
public function testHasParameters_whenNoParameter_returnsFalse() {
|
||||
public function testHasParameters_whenNoParameter_returnsFalse(): void {
|
||||
$query = array();
|
||||
$user_query = new FreshRSS_UserQuery($query);
|
||||
$this->assertFalse($user_query->hasParameters());
|
||||
}
|
||||
|
||||
public function testHasParameters_whenParameter_returnTrue() {
|
||||
public function testHasParameters_whenParameter_returnTrue(): void {
|
||||
$query = array('get' => 's');
|
||||
$user_query = new FreshRSS_UserQuery($query);
|
||||
$this->assertTrue($user_query->hasParameters());
|
||||
}
|
||||
|
||||
public function testIsDeprecated_whenCategoryExists_returnFalse() {
|
||||
public function testIsDeprecated_whenCategoryExists_returnFalse(): void {
|
||||
/** @var FreshRSS_Category&PHPUnit\Framework\MockObject\MockObject */
|
||||
$cat = $this->createMock('FreshRSS_Category');
|
||||
/** @var FreshRSS_CategoryDAO&PHPUnit\Framework\MockObject\MockObject */
|
||||
$cat_dao = $this->createMock('FreshRSS_CategoryDAO');
|
||||
$cat_dao->expects($this->atLeastOnce())
|
||||
->method('searchById')
|
||||
|
@ -170,7 +176,8 @@ class UserQueryTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertFalse($user_query->isDeprecated());
|
||||
}
|
||||
|
||||
public function testIsDeprecated_whenCategoryDoesNotExist_returnTrue() {
|
||||
public function testIsDeprecated_whenCategoryDoesNotExist_returnTrue(): void {
|
||||
/** @var FreshRSS_CategoryDAO&PHPUnit\Framework\MockObject\MockObject */
|
||||
$cat_dao = $this->createMock('FreshRSS_CategoryDAO');
|
||||
$cat_dao->expects($this->atLeastOnce())
|
||||
->method('searchById')
|
||||
|
@ -181,8 +188,10 @@ class UserQueryTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertTrue($user_query->isDeprecated());
|
||||
}
|
||||
|
||||
public function testIsDeprecated_whenFeedExists_returnFalse() {
|
||||
$feed = $this->createMock('FreshRSS_Feed', array(), array('', false));
|
||||
public function testIsDeprecated_whenFeedExists_returnFalse(): void {
|
||||
/** @var FreshRSS_Feed&PHPUnit\Framework\MockObject\MockObject */
|
||||
$feed = $this->createMock('FreshRSS_Feed');
|
||||
/** @var FreshRSS_FeedDAO&PHPUnit\Framework\MockObject\MockObject */
|
||||
$feed_dao = $this->createMock('FreshRSS_FeedDAO');
|
||||
$feed_dao->expects($this->atLeastOnce())
|
||||
->method('searchById')
|
||||
|
@ -193,7 +202,8 @@ class UserQueryTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertFalse($user_query->isDeprecated());
|
||||
}
|
||||
|
||||
public function testIsDeprecated_whenFeedDoesNotExist_returnTrue() {
|
||||
public function testIsDeprecated_whenFeedDoesNotExist_returnTrue(): void {
|
||||
/** @var FreshRSS_FeedDAO&PHPUnit\Framework\MockObject\MockObject */
|
||||
$feed_dao = $this->createMock('FreshRSS_FeedDAO');
|
||||
$feed_dao->expects($this->atLeastOnce())
|
||||
->method('searchById')
|
||||
|
@ -204,19 +214,19 @@ class UserQueryTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertTrue($user_query->isDeprecated());
|
||||
}
|
||||
|
||||
public function testIsDeprecated_whenAllQuery_returnFalse() {
|
||||
public function testIsDeprecated_whenAllQuery_returnFalse(): void {
|
||||
$query = array('get' => 'a');
|
||||
$user_query = new FreshRSS_UserQuery($query);
|
||||
$this->assertFalse($user_query->isDeprecated());
|
||||
}
|
||||
|
||||
public function testIsDeprecated_whenFavoriteQuery_returnFalse() {
|
||||
public function testIsDeprecated_whenFavoriteQuery_returnFalse(): void {
|
||||
$query = array('get' => 's');
|
||||
$user_query = new FreshRSS_UserQuery($query);
|
||||
$this->assertFalse($user_query->isDeprecated());
|
||||
}
|
||||
|
||||
public function testIsDeprecated_whenUnknownQuery_returnFalse() {
|
||||
public function testIsDeprecated_whenUnknownQuery_returnFalse(): void {
|
||||
$query = array('get' => 'q');
|
||||
$user_query = new FreshRSS_UserQuery($query);
|
||||
$this->assertFalse($user_query->isDeprecated());
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
class passwordUtilTest extends PHPUnit\Framework\TestCase {
|
||||
public function testCheck() {
|
||||
public function testCheck(): void {
|
||||
$password = '1234567';
|
||||
|
||||
$ok = FreshRSS_password_Util::check($password);
|
||||
|
@ -9,7 +9,7 @@ class passwordUtilTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertTrue($ok);
|
||||
}
|
||||
|
||||
public function testCheckReturnsFalseIfEmpty() {
|
||||
public function testCheckReturnsFalseIfEmpty(): void {
|
||||
$password = '';
|
||||
|
||||
$ok = FreshRSS_password_Util::check($password);
|
||||
|
@ -17,7 +17,7 @@ class passwordUtilTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertFalse($ok);
|
||||
}
|
||||
|
||||
public function testCheckReturnsFalseIfLessThan7Characters() {
|
||||
public function testCheckReturnsFalseIfLessThan7Characters(): void {
|
||||
$password = '123456';
|
||||
|
||||
$ok = FreshRSS_password_Util::check($password);
|
||||
|
|
|
@ -4,6 +4,7 @@ require_once __DIR__ . '/../../../cli/i18n/I18nCompletionValidator.php';
|
|||
require_once __DIR__ . '/../../../cli/i18n/I18nValue.php';
|
||||
|
||||
class I18nCompletionValidatorTest extends PHPUnit\Framework\TestCase {
|
||||
/** @var I18nValue&PHPUnit\Framework\MockObject\MockObject */
|
||||
private $value;
|
||||
|
||||
public function setUp(): void {
|
||||
|
@ -12,7 +13,7 @@ class I18nCompletionValidatorTest extends PHPUnit\Framework\TestCase {
|
|||
->getMock();
|
||||
}
|
||||
|
||||
public function testDisplayReport() {
|
||||
public function testDisplayReport(): void {
|
||||
$validator = new I18nCompletionValidator([], []);
|
||||
|
||||
$this->assertEquals("There is no data.\n", $validator->displayReport());
|
||||
|
@ -40,13 +41,13 @@ class I18nCompletionValidatorTest extends PHPUnit\Framework\TestCase {
|
|||
$validator->displayReport();
|
||||
}
|
||||
|
||||
public function testValidateWhenNoData() {
|
||||
public function testValidateWhenNoData(): void {
|
||||
$validator = new I18nCompletionValidator([], []);
|
||||
$this->assertTrue($validator->validate());
|
||||
$this->assertEquals('', $validator->displayResult());
|
||||
}
|
||||
|
||||
public function testValidateWhenKeyIsMissing() {
|
||||
public function testValidateWhenKeyIsMissing(): void {
|
||||
$validator = new I18nCompletionValidator([
|
||||
'file1.php' => [
|
||||
'file1.l1.l2.k1' => $this->value,
|
||||
|
@ -60,7 +61,7 @@ class I18nCompletionValidatorTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals("Missing key file1.l1.l2.k1\nMissing key file2.l1.l2.k1\n", $validator->displayResult());
|
||||
}
|
||||
|
||||
public function testValidateWhenKeyIsIgnored() {
|
||||
public function testValidateWhenKeyIsIgnored(): void {
|
||||
$this->value->expects($this->exactly(2))
|
||||
->method('isIgnore')
|
||||
->willReturn(true);
|
||||
|
@ -85,7 +86,7 @@ class I18nCompletionValidatorTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals('', $validator->displayResult());
|
||||
}
|
||||
|
||||
public function testValidateWhenValueIsEqual() {
|
||||
public function testValidateWhenValueIsEqual(): void {
|
||||
$this->value->expects($this->exactly(2))
|
||||
->method('isIgnore')
|
||||
->willReturn(false);
|
||||
|
@ -113,7 +114,7 @@ class I18nCompletionValidatorTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals("Untranslated key file1.l1.l2.k1 - \nUntranslated key file2.l1.l2.k1 - \n", $validator->displayResult());
|
||||
}
|
||||
|
||||
public function testValidateWhenValueIsDifferent() {
|
||||
public function testValidateWhenValueIsDifferent(): void {
|
||||
$this->value->expects($this->exactly(2))
|
||||
->method('isIgnore')
|
||||
->willReturn(false);
|
||||
|
|
|
@ -4,7 +4,9 @@ require_once __DIR__ . '/../../../cli/i18n/I18nData.php';
|
|||
require_once __DIR__ . '/../../../cli/i18n/I18nValue.php';
|
||||
|
||||
class I18nDataTest extends PHPUnit\Framework\TestCase {
|
||||
/** @var array<string,array<string,array<string,I18nValue>>> */
|
||||
private $referenceData;
|
||||
/** @var I18nValue&PHPUnit\Framework\MockObject\MockObject */
|
||||
private $value;
|
||||
|
||||
public function setUp(): void {
|
||||
|
@ -31,12 +33,12 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
];
|
||||
}
|
||||
|
||||
public function testConstructWhenReferenceOnly() {
|
||||
public function testConstructWhenReferenceOnly(): void {
|
||||
$data = new I18nData($this->referenceData);
|
||||
$this->assertEquals($this->referenceData, $data->getData());
|
||||
}
|
||||
|
||||
public function testConstructorWhenLanguageIsMissingFile() {
|
||||
public function testConstructorWhenLanguageIsMissingFile(): void {
|
||||
$rawData = array_merge($this->referenceData, [
|
||||
'fr' => [
|
||||
'file1.php' => [
|
||||
|
@ -79,7 +81,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
], $data->getData());
|
||||
}
|
||||
|
||||
public function testConstructorWhenLanguageIsMissingKeys() {
|
||||
public function testConstructorWhenLanguageIsMissingKeys(): void {
|
||||
$rawData = array_merge($this->referenceData, [
|
||||
'fr' => [
|
||||
'file1.php' => [
|
||||
|
@ -125,7 +127,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
], $data->getData());
|
||||
}
|
||||
|
||||
public function testConstructorWhenLanguageHasExtraKeys() {
|
||||
public function testConstructorWhenLanguageHasExtraKeys(): void {
|
||||
$rawData = array_merge($this->referenceData, [
|
||||
'fr' => [
|
||||
'file1.php' => [
|
||||
|
@ -179,7 +181,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
], $data->getData());
|
||||
}
|
||||
|
||||
public function testConstructorWhenValueIsIdenticalAndIsMarkedAsIgnore() {
|
||||
public function testConstructorWhenValueIsIdenticalAndIsMarkedAsIgnore(): void {
|
||||
$value = $this->getMockBuilder(I18nValue::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
@ -204,7 +206,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
new I18nData($rawData);
|
||||
}
|
||||
|
||||
public function testConstructorWhenValueIsIdenticalAndIsNotMarkedAsIgnore() {
|
||||
public function testConstructorWhenValueIsIdenticalAndIsNotMarkedAsIgnore(): void {
|
||||
$value = $this->getMockBuilder(I18nValue::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
@ -229,7 +231,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
new I18nData($rawData);
|
||||
}
|
||||
|
||||
public function testConstructorWhenValueIsDifferentAndIsMarkedAsToDo() {
|
||||
public function testConstructorWhenValueIsDifferentAndIsMarkedAsToDo(): void {
|
||||
$value = $this->getMockBuilder(I18nValue::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
@ -249,7 +251,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
new I18nData($rawData);
|
||||
}
|
||||
|
||||
public function testConstructorWhenValueIsDifferentAndIsNotMarkedAsTodo() {
|
||||
public function testConstructorWhenValueIsDifferentAndIsNotMarkedAsTodo(): void {
|
||||
$value = $this->getMockBuilder(I18nValue::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
@ -269,7 +271,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
new I18nData($rawData);
|
||||
}
|
||||
|
||||
public function testGetAvailableLanguagesWhenTheyAreSorted() {
|
||||
public function testGetAvailableLanguagesWhenTheyAreSorted(): void {
|
||||
$rawData = array_merge($this->referenceData, [
|
||||
'fr' => [],
|
||||
'nl' => [],
|
||||
|
@ -282,7 +284,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
], $data->getAvailableLanguages());
|
||||
}
|
||||
|
||||
public function testGetAvailableLanguagesWhenTheyAreNotSorted() {
|
||||
public function testGetAvailableLanguagesWhenTheyAreNotSorted(): void {
|
||||
$rawData = array_merge($this->referenceData, [
|
||||
'nl' => [],
|
||||
'fr' => [],
|
||||
|
@ -297,14 +299,14 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
], $data->getAvailableLanguages());
|
||||
}
|
||||
|
||||
public function testAddLanguageWhenLanguageExists() {
|
||||
public function testAddLanguageWhenLanguageExists(): void {
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage('The selected language already exist.');
|
||||
$data = new I18nData($this->referenceData);
|
||||
$data->addLanguage('en');
|
||||
}
|
||||
|
||||
public function testAddLanguageWhenNoReferenceProvided() {
|
||||
public function testAddLanguageWhenNoReferenceProvided(): void {
|
||||
$data = new I18nData($this->referenceData);
|
||||
$data->addLanguage('fr');
|
||||
$this->assertEquals([
|
||||
|
@ -341,7 +343,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
], $data->getData());
|
||||
}
|
||||
|
||||
public function testAddLanguageWhenUnknownReferenceProvided() {
|
||||
public function testAddLanguageWhenUnknownReferenceProvided(): void {
|
||||
$data = new I18nData($this->referenceData);
|
||||
$data->addLanguage('fr', 'unknown');
|
||||
$this->assertEquals([
|
||||
|
@ -378,7 +380,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
], $data->getData());
|
||||
}
|
||||
|
||||
public function testAddLanguageWhenKnownReferenceProvided() {
|
||||
public function testAddLanguageWhenKnownReferenceProvided(): void {
|
||||
$data = new I18nData($this->referenceData);
|
||||
$data->addLanguage('fr', 'en');
|
||||
$this->assertEquals([
|
||||
|
@ -415,24 +417,24 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
], $data->getData());
|
||||
}
|
||||
|
||||
public function testIsKnownWhenKeyExists() {
|
||||
public function testIsKnownWhenKeyExists(): void {
|
||||
$data = new I18nData($this->referenceData);
|
||||
$this->assertTrue($data->isKnown('file2.l1.l2.k2'));
|
||||
}
|
||||
|
||||
public function testIsKnownWhenKeyDoesNotExist() {
|
||||
public function testIsKnownWhenKeyDoesNotExist(): void {
|
||||
$data = new I18nData($this->referenceData);
|
||||
$this->assertFalse($data->isKnown('file2.l1.l2.k3'));
|
||||
}
|
||||
|
||||
public function testAddKeyWhenKeyExists() {
|
||||
public function testAddKeyWhenKeyExists(): void {
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage('The selected key already exist.');
|
||||
$data = new I18nData($this->referenceData);
|
||||
$data->addKey('file2.l1.l2.k1', 'value');
|
||||
}
|
||||
|
||||
public function testAddKeyWhenParentKeyExists() {
|
||||
public function testAddKeyWhenParentKeyExists(): void {
|
||||
$rawData = array_merge($this->referenceData, [
|
||||
'fr' => [],
|
||||
]);
|
||||
|
@ -447,7 +449,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertTrue($data->isKnown('file2.l1.l2.k1.sk1'));
|
||||
}
|
||||
|
||||
public function testAddKeyWhenKeyIsParent() {
|
||||
public function testAddKeyWhenKeyIsParent(): void {
|
||||
$rawData = array_merge($this->referenceData, [
|
||||
'fr' => [],
|
||||
]);
|
||||
|
@ -462,7 +464,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertTrue($data->isKnown('file1.l1.l2.k2'));
|
||||
}
|
||||
|
||||
public function testAddKey() {
|
||||
public function testAddKey(): void {
|
||||
$getTargetedValue = static function (I18nData $data, string $language) {
|
||||
return $data->getData()[$language]['file2.php']['file2.l1.l2.k3'];
|
||||
};
|
||||
|
@ -484,21 +486,21 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals($frValue, $enValue);
|
||||
}
|
||||
|
||||
public function testAddValueWhenLanguageDoesNotExist() {
|
||||
public function testAddValueWhenLanguageDoesNotExist(): void {
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage('The selected language does not exist.');
|
||||
$data = new I18nData($this->referenceData);
|
||||
$data->addValue('file2.l1.l2.k2', 'new value', 'fr');
|
||||
}
|
||||
|
||||
public function testAddValueWhenKeyDoesNotExist() {
|
||||
public function testAddValueWhenKeyDoesNotExist(): void {
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage('The selected key does not exist for the selected language.');
|
||||
$data = new I18nData($this->referenceData);
|
||||
$data->addValue('unknown key', 'new value', 'en');
|
||||
}
|
||||
|
||||
public function testAddValueWhenLanguageIsReferenceAndValueInOtherLanguageHasNotChange() {
|
||||
public function testAddValueWhenLanguageIsReferenceAndValueInOtherLanguageHasNotChange(): void {
|
||||
$getTargetedValue = static function (I18nData $data, string $language) {
|
||||
return $data->getData()[$language]['file2.php']['file2.l1.l2.k2'];
|
||||
};
|
||||
|
@ -526,7 +528,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals('new value', $afterFrValue->getValue());
|
||||
}
|
||||
|
||||
public function testAddValueWhenLanguageIsReferenceAndValueInOtherLanguageHasChange() {
|
||||
public function testAddValueWhenLanguageIsReferenceAndValueInOtherLanguageHasChange(): void {
|
||||
$getTargetedValue = static function (I18nData $data, string $language) {
|
||||
return $data->getData()[$language]['file2.php']['file2.l1.l2.k2'];
|
||||
};
|
||||
|
@ -561,7 +563,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals($value, $afterFrValue);
|
||||
}
|
||||
|
||||
public function testAddValueWhenLanguageIsNotReference() {
|
||||
public function testAddValueWhenLanguageIsNotReference(): void {
|
||||
$getTargetedValue = static function (I18nData $data, string $language) {
|
||||
return $data->getData()[$language]['file2.php']['file2.l1.l2.k2'];
|
||||
};
|
||||
|
@ -583,21 +585,21 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals('new value', $afterFrValue->getValue());
|
||||
}
|
||||
|
||||
public function testRemoveKeyWhenKeyDoesNotExist() {
|
||||
public function testRemoveKeyWhenKeyDoesNotExist(): void {
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage('The selected key does not exist.');
|
||||
$data = new I18nData($this->referenceData);
|
||||
$data->removeKey('Unknown key');
|
||||
}
|
||||
|
||||
public function testRemoveKeyWhenKeyHasNoEmptySibling() {
|
||||
public function testRemoveKeyWhenKeyHasNoEmptySibling(): void {
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage('The selected key does not exist.');
|
||||
$data = new I18nData($this->referenceData);
|
||||
$data->removeKey('file1.l1.l2');
|
||||
}
|
||||
|
||||
public function testRemoveKeyWhenKeyIsEmptySibling() {
|
||||
public function testRemoveKeyWhenKeyIsEmptySibling(): void {
|
||||
$rawData = array_merge($this->referenceData, [
|
||||
'fr' => [],
|
||||
]);
|
||||
|
@ -635,7 +637,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
], $data->getData());
|
||||
}
|
||||
|
||||
public function testRemoveKeyWhenKeyIsTheOnlyChild() {
|
||||
public function testRemoveKeyWhenKeyIsTheOnlyChild(): void {
|
||||
$rawData = array_merge($this->referenceData, [
|
||||
'fr' => [],
|
||||
]);
|
||||
|
@ -673,7 +675,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
], $data->getData());
|
||||
}
|
||||
|
||||
public function testIgnore() {
|
||||
public function testIgnore(): void {
|
||||
$value = $this->getMockBuilder(I18nValue::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
@ -695,7 +697,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
$data->ignore('file1.l1.l2.k1', 'fr', false);
|
||||
}
|
||||
|
||||
public function testIgnoreUnmodified() {
|
||||
public function testIgnoreUnmodified(): void {
|
||||
$value = $this->getMockBuilder(I18nValue::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
@ -722,7 +724,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
$data->ignore_unmodified('fr', false);
|
||||
}
|
||||
|
||||
public function testGetLanguage() {
|
||||
public function testGetLanguage(): void {
|
||||
$rawData = array_merge($this->referenceData, [
|
||||
'fr' => [],
|
||||
'nl' => [],
|
||||
|
@ -731,7 +733,7 @@ class I18nDataTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals($this->referenceData['en'], $data->getLanguage('en'));
|
||||
}
|
||||
|
||||
public function testGetReferenceLanguage() {
|
||||
public function testGetReferenceLanguage(): void {
|
||||
$rawData = array_merge($this->referenceData, [
|
||||
'fr' => [],
|
||||
'nl' => [],
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require_once __DIR__ . '/../../../cli/i18n/I18nFile.php';
|
||||
|
||||
class I18nFileTest extends PHPUnit\Framework\TestCase {
|
||||
public function test() {
|
||||
public function test(): void {
|
||||
$before = $this->computeFilesHash();
|
||||
|
||||
$file = new I18nFile();
|
||||
|
@ -15,7 +15,8 @@ class I18nFileTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals($before, $after);
|
||||
}
|
||||
|
||||
private function computeFilesHash() {
|
||||
/** @return array<string,string> */
|
||||
private function computeFilesHash(): array {
|
||||
$hashes = [];
|
||||
|
||||
$dirs = new DirectoryIterator(I18N_PATH);
|
||||
|
|
|
@ -4,6 +4,7 @@ require_once __DIR__ . '/../../../cli/i18n/I18nValue.php';
|
|||
require_once __DIR__ . '/../../../cli/i18n/I18nUsageValidator.php';
|
||||
|
||||
class I18nUsageValidatorTest extends PHPUnit\Framework\TestCase {
|
||||
/** @var I18nValue */
|
||||
private $value;
|
||||
|
||||
public function setUp(): void {
|
||||
|
@ -12,7 +13,7 @@ class I18nUsageValidatorTest extends PHPUnit\Framework\TestCase {
|
|||
->getMock();
|
||||
}
|
||||
|
||||
public function testDisplayReport() {
|
||||
public function testDisplayReport(): void {
|
||||
$validator = new I18nUsageValidator([], []);
|
||||
|
||||
$this->assertEquals("There is no data.\n", $validator->displayReport());
|
||||
|
@ -40,13 +41,13 @@ class I18nUsageValidatorTest extends PHPUnit\Framework\TestCase {
|
|||
$validator->displayReport();
|
||||
}
|
||||
|
||||
public function testValidateWhenNoData() {
|
||||
public function testValidateWhenNoData(): void {
|
||||
$validator = new I18nUsageValidator([], []);
|
||||
$this->assertTrue($validator->validate());
|
||||
$this->assertEquals('', $validator->displayResult());
|
||||
}
|
||||
|
||||
public function testValidateWhenParentKeyExistsWithoutTransformation() {
|
||||
public function testValidateWhenParentKeyExistsWithoutTransformation(): void {
|
||||
$validator = new I18nUsageValidator([
|
||||
'file1' => [
|
||||
'file1.l1.l2._' => $this->value,
|
||||
|
@ -62,7 +63,7 @@ class I18nUsageValidatorTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals('', $validator->displayResult());
|
||||
}
|
||||
|
||||
public function testValidateWhenParentKeyExistsWithTransformation() {
|
||||
public function testValidateWhenParentKeyExistsWithTransformation(): void {
|
||||
$validator = new I18nUsageValidator([
|
||||
'file1' => [
|
||||
'file1.l1.l2._' => $this->value,
|
||||
|
@ -78,7 +79,7 @@ class I18nUsageValidatorTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals('', $validator->displayResult());
|
||||
}
|
||||
|
||||
public function testValidateWhenParentKeyDoesNotExist() {
|
||||
public function testValidateWhenParentKeyDoesNotExist(): void {
|
||||
$validator = new I18nUsageValidator([
|
||||
'file1' => [
|
||||
'file1.l1.l2._' => $this->value,
|
||||
|
@ -91,7 +92,7 @@ class I18nUsageValidatorTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals("Unused key file1.l1.l2._ - \nUnused key file2.l1.l2._ - \n", $validator->displayResult());
|
||||
}
|
||||
|
||||
public function testValidateWhenChildKeyExists() {
|
||||
public function testValidateWhenChildKeyExists(): void {
|
||||
$validator = new I18nUsageValidator([
|
||||
'file1' => [
|
||||
'file1.l1.l2.k1' => $this->value,
|
||||
|
@ -107,7 +108,7 @@ class I18nUsageValidatorTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals('', $validator->displayResult());
|
||||
}
|
||||
|
||||
public function testValidateWhenChildKeyDoesNotExist() {
|
||||
public function testValidateWhenChildKeyDoesNotExist(): void {
|
||||
$validator = new I18nUsageValidator([
|
||||
'file1' => [
|
||||
'file1.l1.l2.k1' => $this->value,
|
||||
|
|
|
@ -3,35 +3,35 @@
|
|||
require_once __DIR__ . '/../../../cli/i18n/I18nValue.php';
|
||||
|
||||
class I18nValueTest extends PHPUnit\Framework\TestCase {
|
||||
public function testConstructorWithoutState() {
|
||||
public function testConstructorWithoutState(): void {
|
||||
$value = new I18nValue('some value');
|
||||
$this->assertEquals('some value', $value->getValue());
|
||||
$this->assertFalse($value->isIgnore());
|
||||
$this->assertFalse($value->isTodo());
|
||||
}
|
||||
|
||||
public function testConstructorWithUnknownState() {
|
||||
public function testConstructorWithUnknownState(): void {
|
||||
$value = new I18nValue('some value -> unknown');
|
||||
$this->assertEquals('some value', $value->getValue());
|
||||
$this->assertFalse($value->isIgnore());
|
||||
$this->assertFalse($value->isTodo());
|
||||
}
|
||||
|
||||
public function testConstructorWithTodoState() {
|
||||
public function testConstructorWithTodoState(): void {
|
||||
$value = new I18nValue('some value -> todo');
|
||||
$this->assertEquals('some value', $value->getValue());
|
||||
$this->assertFalse($value->isIgnore());
|
||||
$this->assertTrue($value->isTodo());
|
||||
}
|
||||
|
||||
public function testConstructorWithIgnoreState() {
|
||||
public function testConstructorWithIgnoreState(): void {
|
||||
$value = new I18nValue('some value -> ignore');
|
||||
$this->assertEquals('some value', $value->getValue());
|
||||
$this->assertTrue($value->isIgnore());
|
||||
$this->assertFalse($value->isTodo());
|
||||
}
|
||||
|
||||
public function testClone() {
|
||||
public function testClone(): void {
|
||||
$value = new I18nValue('some value');
|
||||
$clonedValue = clone $value;
|
||||
$this->assertEquals('some value', $value->getValue());
|
||||
|
@ -42,21 +42,21 @@ class I18nValueTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertTrue($clonedValue->isTodo());
|
||||
}
|
||||
|
||||
public function testEqualWhenValueIsIdentical() {
|
||||
public function testEqualWhenValueIsIdentical(): void {
|
||||
$value = new I18nValue('some value');
|
||||
$clonedValue = clone $value;
|
||||
$this->assertTrue($value->equal($clonedValue));
|
||||
$this->assertTrue($clonedValue->equal($value));
|
||||
}
|
||||
|
||||
public function testEqualWhenValueIsDifferent() {
|
||||
public function testEqualWhenValueIsDifferent(): void {
|
||||
$value = new I18nValue('some value');
|
||||
$otherValue = new I18nValue('some other value');
|
||||
$this->assertFalse($value->equal($otherValue));
|
||||
$this->assertFalse($otherValue->equal($value));
|
||||
}
|
||||
|
||||
public function testStates() {
|
||||
public function testStates(): void {
|
||||
$reflectionProperty = new ReflectionProperty(I18nValue::class, 'state');
|
||||
$reflectionProperty->setAccessible(true);
|
||||
|
||||
|
@ -74,7 +74,7 @@ class I18nValueTest extends PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals('todo', $reflectionProperty->getValue($value));
|
||||
}
|
||||
|
||||
public function testToString() {
|
||||
public function testToString(): void {
|
||||
$value = new I18nValue('some value');
|
||||
$this->assertEquals('some value', $value->__toString());
|
||||
$value->markAsTodo();
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
class FreshRSS_Migration_2019_12_22_FooBar {
|
||||
/**
|
||||
* @return boolean true if the migration was successful, false otherwise
|
||||
* @return bool true if the migration was successful, false otherwise
|
||||
*/
|
||||
public static function migrate() {
|
||||
public static function migrate(): bool {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
class FreshRSS_Migration_2019_12_23_Baz {
|
||||
/**
|
||||
* @return boolean true if the migration was successful, false otherwise
|
||||
* @return bool true if the migration was successful, false otherwise
|
||||
*/
|
||||
public static function migrate() {
|
||||
public static function migrate(): bool {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
class FreshRSS_Migration_2020_01_11_FooBar {
|
||||
/**
|
||||
* @return boolean true if the migration was successful, false otherwise
|
||||
* @return bool true if the migration was successful, false otherwise
|
||||
*/
|
||||
public static function migrate() {
|
||||
public static function migrate(): bool {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
class FreshRSS_Migration_2020_01_12_Baz {
|
||||
/**
|
||||
* @return boolean true if the migration was successful, false otherwise
|
||||
* @return bool true if the migration was successful, false otherwise
|
||||
*/
|
||||
public static function migrate() {
|
||||
public static function migrate(): bool {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
class CssXPathTest extends PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testCssXPathTranslatorClassExists() {
|
||||
public function testCssXPathTranslatorClassExists(): void {
|
||||
$this->assertTrue(class_exists('Gt\\CssXPath\\Translator'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use PHPUnit\Framework\TestCase;
|
|||
|
||||
class MigratorTest extends TestCase
|
||||
{
|
||||
public function testAddMigration() {
|
||||
public function testAddMigration(): void {
|
||||
$migrator = new Minz_Migrator();
|
||||
|
||||
$migrator->addMigration('foo', function () {
|
||||
|
@ -17,7 +17,7 @@ class MigratorTest extends TestCase
|
|||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testAddMigrationFailsIfUncallableMigration() {
|
||||
public function testAddMigrationFailsIfUncallableMigration(): void {
|
||||
$this->expectException(BadFunctionCallException::class);
|
||||
$this->expectExceptionMessage('foo migration cannot be called.');
|
||||
|
||||
|
@ -25,7 +25,7 @@ class MigratorTest extends TestCase
|
|||
$migrator->addMigration('foo', null);
|
||||
}
|
||||
|
||||
public function testMigrationsIsSorted() {
|
||||
public function testMigrationsIsSorted(): void {
|
||||
$migrator = new Minz_Migrator();
|
||||
$migrator->addMigration('2_foo', function () {
|
||||
return true;
|
||||
|
@ -43,7 +43,7 @@ class MigratorTest extends TestCase
|
|||
$this->assertSame($expected_versions, array_keys($migrations));
|
||||
}
|
||||
|
||||
public function testSetAppliedVersions() {
|
||||
public function testSetAppliedVersions(): void {
|
||||
$migrator = new Minz_Migrator();
|
||||
$migrator->addMigration('foo', function () {
|
||||
return true;
|
||||
|
@ -54,7 +54,7 @@ class MigratorTest extends TestCase
|
|||
$this->assertSame(['foo'], $migrator->appliedVersions());
|
||||
}
|
||||
|
||||
public function testSetAppliedVersionsTrimArgument() {
|
||||
public function testSetAppliedVersionsTrimArgument(): void {
|
||||
$migrator = new Minz_Migrator();
|
||||
$migrator->addMigration('foo', function () {
|
||||
return true;
|
||||
|
@ -65,7 +65,7 @@ class MigratorTest extends TestCase
|
|||
$this->assertSame(['foo'], $migrator->appliedVersions());
|
||||
}
|
||||
|
||||
public function testSetAppliedVersionsFailsIfMigrationDoesNotExist() {
|
||||
public function testSetAppliedVersionsFailsIfMigrationDoesNotExist(): void {
|
||||
$this->expectException(DomainException::class);
|
||||
$this->expectExceptionMessage('foo migration does not exist.');
|
||||
|
||||
|
@ -74,7 +74,7 @@ class MigratorTest extends TestCase
|
|||
$migrator->setAppliedVersions(['foo']);
|
||||
}
|
||||
|
||||
public function testVersions() {
|
||||
public function testVersions(): void {
|
||||
$migrator = new Minz_Migrator();
|
||||
$migrator->addMigration('foo', function () {
|
||||
return true;
|
||||
|
@ -88,7 +88,7 @@ class MigratorTest extends TestCase
|
|||
$this->assertSame(['bar', 'foo'], $versions);
|
||||
}
|
||||
|
||||
public function testMigrate() {
|
||||
public function testMigrate(): void {
|
||||
$migrator = new Minz_Migrator();
|
||||
$spy = false;
|
||||
$migrator->addMigration('foo', function () use (&$spy) {
|
||||
|
@ -106,7 +106,7 @@ class MigratorTest extends TestCase
|
|||
], $result);
|
||||
}
|
||||
|
||||
public function testMigrateCallsMigrationsInSortedOrder() {
|
||||
public function testMigrateCallsMigrationsInSortedOrder(): void {
|
||||
$migrator = new Minz_Migrator();
|
||||
$spy_foo_1_is_called = false;
|
||||
$migrator->addMigration('2_foo', function () use (&$spy_foo_1_is_called) {
|
||||
|
@ -126,7 +126,7 @@ class MigratorTest extends TestCase
|
|||
], $result);
|
||||
}
|
||||
|
||||
public function testMigrateDoesNotCallAppliedMigrations() {
|
||||
public function testMigrateDoesNotCallAppliedMigrations(): void {
|
||||
$migrator = new Minz_Migrator();
|
||||
$spy = false;
|
||||
$migrator->addMigration('1_foo', function () use (&$spy) {
|
||||
|
@ -141,7 +141,7 @@ class MigratorTest extends TestCase
|
|||
$this->assertSame([], $result);
|
||||
}
|
||||
|
||||
public function testMigrateCallNonAppliedBetweenTwoApplied() {
|
||||
public function testMigrateCallNonAppliedBetweenTwoApplied(): void {
|
||||
$migrator = new Minz_Migrator();
|
||||
$migrator->addMigration('1_foo', function () {
|
||||
return true;
|
||||
|
@ -162,7 +162,7 @@ class MigratorTest extends TestCase
|
|||
], $result);
|
||||
}
|
||||
|
||||
public function testMigrateWithMigrationReturningFalseDoesNotApplyVersion() {
|
||||
public function testMigrateWithMigrationReturningFalseDoesNotApplyVersion(): void {
|
||||
$migrator = new Minz_Migrator();
|
||||
$migrator->addMigration('1_foo', function () {
|
||||
return true;
|
||||
|
@ -180,7 +180,7 @@ class MigratorTest extends TestCase
|
|||
], $result);
|
||||
}
|
||||
|
||||
public function testMigrateWithMigrationReturningFalseDoesNotExecuteNextMigrations() {
|
||||
public function testMigrateWithMigrationReturningFalseDoesNotExecuteNextMigrations(): void {
|
||||
$migrator = new Minz_Migrator();
|
||||
$migrator->addMigration('1_foo', function () {
|
||||
return false;
|
||||
|
@ -200,7 +200,7 @@ class MigratorTest extends TestCase
|
|||
], $result);
|
||||
}
|
||||
|
||||
public function testMigrateWithFailingMigration() {
|
||||
public function testMigrateWithFailingMigration(): void {
|
||||
$migrator = new Minz_Migrator();
|
||||
$migrator->addMigration('foo', function () {
|
||||
throw new \Exception('Oops, it failed.');
|
||||
|
@ -214,7 +214,7 @@ class MigratorTest extends TestCase
|
|||
], $result);
|
||||
}
|
||||
|
||||
public function testUpToDate() {
|
||||
public function testUpToDate(): void {
|
||||
$migrator = new Minz_Migrator();
|
||||
$migrator->addMigration('foo', function () {
|
||||
return true;
|
||||
|
@ -226,7 +226,7 @@ class MigratorTest extends TestCase
|
|||
$this->assertTrue($upToDate);
|
||||
}
|
||||
|
||||
public function testUpToDateIfRemainingMigration() {
|
||||
public function testUpToDateIfRemainingMigration(): void {
|
||||
$migrator = new Minz_Migrator();
|
||||
$migrator->addMigration('1_foo', function () {
|
||||
return true;
|
||||
|
@ -241,7 +241,7 @@ class MigratorTest extends TestCase
|
|||
$this->assertFalse($upToDate);
|
||||
}
|
||||
|
||||
public function testUpToDateIfNoMigrations() {
|
||||
public function testUpToDateIfNoMigrations(): void {
|
||||
$migrator = new Minz_Migrator();
|
||||
|
||||
$upToDate = $migrator->upToDate();
|
||||
|
@ -249,7 +249,7 @@ class MigratorTest extends TestCase
|
|||
$this->assertTrue($upToDate);
|
||||
}
|
||||
|
||||
public function testConstructorLoadsDirectory() {
|
||||
public function testConstructorLoadsDirectory(): void {
|
||||
$migrations_path = TESTS_PATH . '/fixtures/migrations/';
|
||||
$migrator = new Minz_Migrator($migrations_path);
|
||||
$expected_versions = ['2019_12_22_FooBar', '2019_12_23_Baz'];
|
||||
|
@ -259,7 +259,7 @@ class MigratorTest extends TestCase
|
|||
$this->assertSame($expected_versions, array_keys($migrations));
|
||||
}
|
||||
|
||||
public function testExecute() {
|
||||
public function testExecute(): void {
|
||||
$migrations_path = TESTS_PATH . '/fixtures/migrations/';
|
||||
$applied_migrations_path = tempnam('/tmp', 'applied_migrations.txt');
|
||||
|
||||
|
@ -271,7 +271,7 @@ class MigratorTest extends TestCase
|
|||
@unlink($applied_migrations_path);
|
||||
}
|
||||
|
||||
public function testExecuteWithAlreadyAppliedMigration() {
|
||||
public function testExecuteWithAlreadyAppliedMigration(): void {
|
||||
$migrations_path = TESTS_PATH . '/fixtures/migrations/';
|
||||
$applied_migrations_path = tempnam('/tmp', 'applied_migrations.txt');
|
||||
file_put_contents($applied_migrations_path, '2019_12_22_FooBar');
|
||||
|
@ -284,7 +284,7 @@ class MigratorTest extends TestCase
|
|||
@unlink($applied_migrations_path);
|
||||
}
|
||||
|
||||
public function testExecuteWithAppliedMigrationInDifferentOrder() {
|
||||
public function testExecuteWithAppliedMigrationInDifferentOrder(): void {
|
||||
$migrations_path = TESTS_PATH . '/fixtures/migrations/';
|
||||
$applied_migrations_path = tempnam('/tmp', 'applied_migrations.txt');
|
||||
file_put_contents($applied_migrations_path, "2019_12_23_Baz\n2019_12_22_FooBar");
|
||||
|
@ -299,7 +299,7 @@ class MigratorTest extends TestCase
|
|||
@unlink($applied_migrations_path);
|
||||
}
|
||||
|
||||
public function testExecuteFailsIfVersionPathDoesNotExist() {
|
||||
public function testExecuteFailsIfVersionPathDoesNotExist(): void {
|
||||
$migrations_path = TESTS_PATH . '/fixtures/migrations/';
|
||||
$applied_migrations_path = tempnam('/tmp', 'applied_migrations.txt');
|
||||
$expected_result = "Cannot open the {$applied_migrations_path} file";
|
||||
|
@ -311,7 +311,7 @@ class MigratorTest extends TestCase
|
|||
@unlink($applied_migrations_path);
|
||||
}
|
||||
|
||||
public function testExecuteFailsIfAMigrationIsFailing() {
|
||||
public function testExecuteFailsIfAMigrationIsFailing(): void {
|
||||
$migrations_path = TESTS_PATH . '/fixtures/migrations_with_failing/';
|
||||
$applied_migrations_path = tempnam('/tmp', 'applied_migrations.txt');
|
||||
$expected_result = 'A migration failed to be applied, please see previous logs.';
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
class PHPMailerTest extends PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testPHPMailerClassExists() {
|
||||
public function testPHPMailerClassExists(): void {
|
||||
$this->assertTrue(class_exists('PHPMailer\\PHPMailer\\PHPMailer'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,48 @@
|
|||
# List of files, which are not yet passing PHPStan level 6 https://phpstan.org/user-guide/rule-levels
|
||||
# https://github.com/FreshRSS/FreshRSS/issues/4112
|
||||
# List of files, which are not yet passing PHPStan level 7 https://phpstan.org/user-guide/rule-levels
|
||||
# Used for automated tests to avoid regressions in files already passing that level.
|
||||
# Can be regenerated with something like:
|
||||
# find . -type d -name 'vendor' -prune -o -name '*.php' -exec sh -c 'vendor/bin/phpstan analyse --level 6 --memory-limit 512M {} >/dev/null 2>/dev/null || echo {}' \;
|
||||
# find . -type d -name 'vendor' -prune -o -name '*.php' -exec sh -c 'vendor/bin/phpstan analyse --level 7 --memory-limit 512M {} >/dev/null 2>/dev/null || echo {}' \;
|
||||
|
||||
./app/install.php
|
||||
./app/Controllers/configureController.php
|
||||
./app/Controllers/feedController.php
|
||||
./app/Controllers/importExportController.php
|
||||
./app/Controllers/indexController.php
|
||||
./app/Controllers/updateController.php
|
||||
./app/Controllers/userController.php
|
||||
./app/Models/CategoryDAO.php
|
||||
./app/Models/Context.php
|
||||
./app/Models/DatabaseDAO.php
|
||||
./app/Models/DatabaseDAOPGSQL.php
|
||||
./app/Models/Entry.php
|
||||
./app/Models/EntryDAO.php
|
||||
./app/Models/Feed.php
|
||||
./app/Models/FeedDAO.php
|
||||
./app/Models/ReadingMode.php
|
||||
./app/Models/Search.php
|
||||
./app/Models/Share.php
|
||||
./app/Models/StatsDAO.php
|
||||
./app/Models/TagDAO.php
|
||||
./app/Models/Themes.php
|
||||
./app/Models/UserQuery.php
|
||||
./app/Services/ExportService.php
|
||||
./app/Services/ImportService.php
|
||||
./lib/Minz/Paginator.php
|
||||
./app/views/helpers/logs_pagination.phtml
|
||||
./app/views/index/reader.phtml
|
||||
./app/views/stats/index.phtml
|
||||
./app/views/stats/repartition.phtml
|
||||
./app/views/user/details.phtml
|
||||
./cli/check.translation.php
|
||||
./cli/delete-user.php
|
||||
./cli/do-install.php
|
||||
./cli/manipulate.translation.php
|
||||
./cli/user-info.php
|
||||
./lib/lib_date.php
|
||||
./lib/Minz/ActionController.php
|
||||
./lib/Minz/Error.php
|
||||
./lib/Minz/Mailer.php
|
||||
./lib/Minz/Migrator.php
|
||||
./lib/Minz/ModelPdo.php
|
||||
./lib/Minz/Request.php
|
||||
./p/api/greader.php
|
||||
./tests/cli/i18n/I18nFileTest.php
|
||||
./tests/lib/Minz/MigratorTest.php
|
||||
|
|
Loading…
Reference in New Issue