diff options
Diffstat (limited to 'app/Models')
| -rw-r--r-- | app/Models/BooleanSearch.php | 18 | ||||
| -rw-r--r-- | app/Models/Category.php | 4 | ||||
| -rw-r--r-- | app/Models/Context.php | 28 | ||||
| -rw-r--r-- | app/Models/Entry.php | 34 | ||||
| -rw-r--r-- | app/Models/Factory.php | 72 | ||||
| -rw-r--r-- | app/Models/Feed.php | 4 | ||||
| -rw-r--r-- | app/Models/FeedDAO.php | 4 | ||||
| -rw-r--r-- | app/Models/FilterAction.php | 4 | ||||
| -rw-r--r-- | app/Models/ReadingMode.php | 13 | ||||
| -rw-r--r-- | app/Models/Search.php | 2 | ||||
| -rw-r--r-- | app/Models/Share.php | 39 | ||||
| -rw-r--r-- | app/Models/StatsDAO.php | 19 | ||||
| -rw-r--r-- | app/Models/StatsDAOPGSQL.php | 19 | ||||
| -rw-r--r-- | app/Models/StatsDAOSQLite.php | 19 | ||||
| -rw-r--r-- | app/Models/Themes.php | 15 | ||||
| -rw-r--r-- | app/Models/UserQuery.php | 15 | ||||
| -rw-r--r-- | app/Models/View.php | 8 |
17 files changed, 118 insertions, 199 deletions
diff --git a/app/Models/BooleanSearch.php b/app/Models/BooleanSearch.php index 50f8feea1..375705036 100644 --- a/app/Models/BooleanSearch.php +++ b/app/Models/BooleanSearch.php @@ -4,20 +4,24 @@ declare(strict_types=1); /** * Contains Boolean search from the search form. */ -class FreshRSS_BooleanSearch { +class FreshRSS_BooleanSearch implements \Stringable { private string $raw_input = ''; /** @var array<FreshRSS_BooleanSearch|FreshRSS_Search> */ private array $searches = []; /** - * @phpstan-var 'AND'|'OR'|'AND NOT'|'OR NOT' + * @param string $input + * @param int $level + * @param 'AND'|'OR'|'AND NOT'|'OR NOT' $operator + * @param bool $allowUserQueries */ - private string $operator; - - /** @param 'AND'|'OR'|'AND NOT'|'OR NOT' $operator */ - public function __construct(string $input, int $level = 0, string $operator = 'AND', bool $allowUserQueries = true) { - $this->operator = $operator; + public function __construct( + string $input, + int $level = 0, + private readonly string $operator = 'AND', + bool $allowUserQueries = true + ) { $input = trim($input); if ($input === '') { return; diff --git a/app/Models/Category.php b/app/Models/Category.php index 5c346844a..cd8145e0c 100644 --- a/app/Models/Category.php +++ b/app/Models/Category.php @@ -243,9 +243,7 @@ class FreshRSS_Category extends Minz_Model { if ($this->feeds === null) { return; } - uasort($this->feeds, static function (FreshRSS_Feed $a, FreshRSS_Feed $b) { - return strnatcasecmp($a->name(), $b->name()); - }); + uasort($this->feeds, static fn(FreshRSS_Feed $a, FreshRSS_Feed $b) => strnatcasecmp($a->name(), $b->name())); } /** diff --git a/app/Models/Context.php b/app/Models/Context.php index 26212a0ef..f39fd0eca 100644 --- a/app/Models/Context.php +++ b/app/Models/Context.php @@ -347,24 +347,16 @@ final class FreshRSS_Context { $type = substr($get, 0, 1); $id = substr($get, 2); - switch ($type) { - case 'a': - return self::$current_get['all']; - case 'i': - return self::$current_get['important']; - case 's': - return self::$current_get['starred']; - case 'f': - return self::$current_get['feed'] == $id; - case 'c': - return self::$current_get['category'] == $id; - case 't': - return self::$current_get['tag'] == $id; - case 'T': - return self::$current_get['tags'] || self::$current_get['tag']; - default: - return false; - } + return match ($type) { + 'a' => self::$current_get['all'], + 'i' => self::$current_get['important'], + 's' => self::$current_get['starred'], + 'f' => self::$current_get['feed'] == $id, + 'c' => self::$current_get['category'] == $id, + 't' => self::$current_get['tag'] == $id, + 'T' => self::$current_get['tags'] || self::$current_get['tag'], + default => false, + }; } /** diff --git a/app/Models/Entry.php b/app/Models/Entry.php index 6e87fe5cd..747bebd71 100644 --- a/app/Models/Entry.php +++ b/app/Models/Entry.php @@ -168,7 +168,7 @@ class FreshRSS_Entry extends Minz_Model { $medium = $enclosure['medium'] ?? ''; $mime = $enclosure['type'] ?? ''; - return ($elink != '' && $medium === 'image') || strpos($mime, 'image') === 0 || + return ($elink != '' && $medium === 'image') || str_starts_with($mime, 'image') || ($mime == '' && $length == 0 && preg_match('/[.](avif|gif|jpe?g|png|svg|webp)([?#]|$)/i', $elink)); } @@ -242,12 +242,12 @@ HTML; if (self::enclosureIsImage($enclosure)) { $content .= '<p class="enclosure-content"><img src="' . $elink . '" alt="" title="' . $etitle . '" /></p>'; - } elseif ($medium === 'audio' || strpos($mime, 'audio') === 0) { + } elseif ($medium === 'audio' || str_starts_with($mime, 'audio')) { $content .= '<p class="enclosure-content"><audio preload="none" src="' . $elink . ($length == null ? '' : '" data-length="' . (int)$length) . ($mime == '' ? '' : '" data-type="' . htmlspecialchars($mime, ENT_COMPAT, 'UTF-8')) . '" controls="controls" title="' . $etitle . '"></audio> <a download="" href="' . $elink . '">💾</a></p>'; - } elseif ($medium === 'video' || strpos($mime, 'video') === 0) { + } elseif ($medium === 'video' || str_starts_with($mime, 'video')) { $content .= '<p class="enclosure-content"><video preload="none" src="' . $elink . ($length == null ? '' : '" data-length="' . (int)$length) . ($mime == '' ? '' : '" data-type="' . htmlspecialchars($mime, ENT_COMPAT, 'UTF-8')) @@ -285,7 +285,7 @@ HTML; yield from $attributeEnclosures; } try { - $searchEnclosures = !is_iterable($attributeEnclosures) && (strpos($this->content, '<p class="enclosure-content') !== false); + $searchEnclosures = !is_iterable($attributeEnclosures) && (str_contains($this->content, '<p class="enclosure-content')); $searchBodyImages &= (stripos($this->content, '<img') !== false); $xpath = null; if ($searchEnclosures || $searchBodyImages) { @@ -498,7 +498,7 @@ HTML; public function _authors($value): void { $this->hash = ''; if (!is_array($value)) { - if (strpos($value, ';') !== false) { + if (str_contains($value, ';')) { $value = htmlspecialchars_decode($value, ENT_QUOTES); $value = preg_split('/\s*[;]\s*/', $value, -1, PREG_SPLIT_NO_EMPTY) ?: []; $value = Minz_Helper::htmlspecialchars_utf8($value); @@ -568,21 +568,13 @@ HTML; foreach ($booleanSearch->searches() as $filter) { if ($filter instanceof FreshRSS_BooleanSearch) { // BooleanSearches are combined by AND (default) or OR or AND NOT (special cases) operators and are recursive - switch ($filter->operator()) { - case 'OR': - $ok |= $this->matches($filter); - break; - case 'OR NOT': - $ok |= !$this->matches($filter); - break; - case 'AND NOT': - $ok &= !$this->matches($filter); - break; - case 'AND': - default: - $ok &= $this->matches($filter); - break; - } + match ($filter->operator()) { + 'AND' => $ok &= $this->matches($filter), + 'OR' => $ok |= $this->matches($filter), + 'AND NOT' => $ok &= !$this->matches($filter), + 'OR NOT' => $ok |= !$this->matches($filter), + default => $ok &= $this->matches($filter), + }; } elseif ($filter instanceof FreshRSS_Search) { // Searches are combined by OR and are not recursive $ok = true; @@ -836,7 +828,7 @@ HTML; $base = $xpath->evaluate('normalize-space(//base/@href)'); if ($base == false || !is_string($base)) { $base = $url; - } elseif (substr($base, 0, 2) === '//') { + } elseif (str_starts_with($base, '//')) { //Protocol-relative URLs "//www.example.net" $base = (parse_url($url, PHP_URL_SCHEME) ?? 'https') . ':' . $base; } diff --git a/app/Models/Factory.php b/app/Models/Factory.php index be96c0e58..6c140475e 100644 --- a/app/Models/Factory.php +++ b/app/Models/Factory.php @@ -14,79 +14,63 @@ class FreshRSS_Factory { * @throws Minz_ConfigurationNamespaceException|Minz_PDOConnectionException */ public static function createCategoryDao(?string $username = null): FreshRSS_CategoryDAO { - switch (FreshRSS_Context::systemConf()->db['type'] ?? '') { - case 'sqlite': - return new FreshRSS_CategoryDAOSQLite($username); - default: - return new FreshRSS_CategoryDAO($username); - } + return match (FreshRSS_Context::systemConf()->db['type'] ?? '') { + 'sqlite' => new FreshRSS_CategoryDAOSQLite($username), + default => new FreshRSS_CategoryDAO($username), + }; } /** * @throws Minz_ConfigurationNamespaceException|Minz_PDOConnectionException */ public static function createFeedDao(?string $username = null): FreshRSS_FeedDAO { - switch (FreshRSS_Context::systemConf()->db['type'] ?? '') { - case 'sqlite': - return new FreshRSS_FeedDAOSQLite($username); - default: - return new FreshRSS_FeedDAO($username); - } + return match (FreshRSS_Context::systemConf()->db['type'] ?? '') { + 'sqlite' => new FreshRSS_FeedDAOSQLite($username), + default => new FreshRSS_FeedDAO($username), + }; } /** * @throws Minz_ConfigurationNamespaceException|Minz_PDOConnectionException */ public static function createEntryDao(?string $username = null): FreshRSS_EntryDAO { - switch (FreshRSS_Context::systemConf()->db['type'] ?? '') { - case 'sqlite': - return new FreshRSS_EntryDAOSQLite($username); - case 'pgsql': - return new FreshRSS_EntryDAOPGSQL($username); - default: - return new FreshRSS_EntryDAO($username); - } + return match (FreshRSS_Context::systemConf()->db['type'] ?? '') { + 'sqlite' => new FreshRSS_EntryDAOSQLite($username), + 'pgsql' => new FreshRSS_EntryDAOPGSQL($username), + default => new FreshRSS_EntryDAO($username), + }; } /** * @throws Minz_ConfigurationNamespaceException|Minz_PDOConnectionException */ public static function createTagDao(?string $username = null): FreshRSS_TagDAO { - switch (FreshRSS_Context::systemConf()->db['type'] ?? '') { - case 'sqlite': - return new FreshRSS_TagDAOSQLite($username); - case 'pgsql': - return new FreshRSS_TagDAOPGSQL($username); - default: - return new FreshRSS_TagDAO($username); - } + return match (FreshRSS_Context::systemConf()->db['type'] ?? '') { + 'sqlite' => new FreshRSS_TagDAOSQLite($username), + 'pgsql' => new FreshRSS_TagDAOPGSQL($username), + default => new FreshRSS_TagDAO($username), + }; } /** * @throws Minz_ConfigurationNamespaceException|Minz_PDOConnectionException */ public static function createStatsDAO(?string $username = null): FreshRSS_StatsDAO { - switch (FreshRSS_Context::systemConf()->db['type'] ?? '') { - case 'sqlite': - return new FreshRSS_StatsDAOSQLite($username); - case 'pgsql': - return new FreshRSS_StatsDAOPGSQL($username); - default: - return new FreshRSS_StatsDAO($username); - } + return match (FreshRSS_Context::systemConf()->db['type'] ?? '') { + 'sqlite' => new FreshRSS_StatsDAOSQLite($username), + 'pgsql' => new FreshRSS_StatsDAOPGSQL($username), + default => new FreshRSS_StatsDAO($username), + }; } /** * @throws Minz_ConfigurationNamespaceException|Minz_PDOConnectionException */ public static function createDatabaseDAO(?string $username = null): FreshRSS_DatabaseDAO { - switch (FreshRSS_Context::systemConf()->db['type'] ?? '') { - case 'sqlite': - return new FreshRSS_DatabaseDAOSQLite($username); - case 'pgsql': - return new FreshRSS_DatabaseDAOPGSQL($username); - default: - return new FreshRSS_DatabaseDAO($username); - } + return match (FreshRSS_Context::systemConf()->db['type'] ?? '') { + 'sqlite' => new FreshRSS_DatabaseDAOSQLite($username), + 'pgsql' => new FreshRSS_DatabaseDAOPGSQL($username), + default => new FreshRSS_DatabaseDAO($username), + }; } } diff --git a/app/Models/Feed.php b/app/Models/Feed.php index 2aa0baa9d..489062316 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -358,7 +358,7 @@ class FreshRSS_Feed extends Minz_Model { } else { $simplePie = customSimplePie($this->attributes(), $this->curlOptions()); $url = htmlspecialchars_decode($this->url, ENT_QUOTES); - if (substr($url, -11) === '#force_feed') { + if (str_ends_with($url, '#force_feed')) { $simplePie->force_feed(true); $url = substr($url, 0, -11); } @@ -1167,7 +1167,7 @@ class FreshRSS_Feed extends Minz_Model { ' via hub ' . $hubJson['hub'] . ' with callback ' . $callbackUrl . ': ' . $info['http_code'] . ' ' . $response, PSHB_LOG); - if (substr('' . $info['http_code'], 0, 1) == '2') { + if (str_starts_with('' . $info['http_code'], '2')) { return true; } else { $hubJson['lease_start'] = time(); //Prevent trying again too soon diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php index ea6e7fc55..bb4209eca 100644 --- a/app/Models/FeedDAO.php +++ b/app/Models/FeedDAO.php @@ -424,9 +424,7 @@ SQL; */ $feeds = self::daoToFeeds($res); - uasort($feeds, static function (FreshRSS_Feed $a, FreshRSS_Feed $b) { - return strnatcasecmp($a->name(), $b->name()); - }); + uasort($feeds, static fn(FreshRSS_Feed $a, FreshRSS_Feed $b) => strnatcasecmp($a->name(), $b->name())); return $feeds; } diff --git a/app/Models/FilterAction.php b/app/Models/FilterAction.php index bf5a79fe7..eb8ea8502 100644 --- a/app/Models/FilterAction.php +++ b/app/Models/FilterAction.php @@ -3,13 +3,11 @@ declare(strict_types=1); class FreshRSS_FilterAction { - private FreshRSS_BooleanSearch $booleanSearch; /** @var array<string>|null */ private ?array $actions = null; /** @param array<string> $actions */ - private function __construct(FreshRSS_BooleanSearch $booleanSearch, array $actions) { - $this->booleanSearch = $booleanSearch; + private function __construct(private readonly FreshRSS_BooleanSearch $booleanSearch, array $actions) { $this->_actions($actions); } diff --git a/app/Models/ReadingMode.php b/app/Models/ReadingMode.php index 035b22114..60c7e76e1 100644 --- a/app/Models/ReadingMode.php +++ b/app/Models/ReadingMode.php @@ -6,23 +6,14 @@ declare(strict_types=1); */ class FreshRSS_ReadingMode { - protected string $id; protected string $name; - protected string $title; - /** @var array{c:string,a:string,params:array<string,mixed>} */ - protected array $urlParams; - protected bool $isActive = false; /** * ReadingMode constructor. * @param array{c:string,a:string,params:array<string,mixed>} $urlParams */ - public function __construct(string $id, string $title, array $urlParams, bool $active) { - $this->id = $id; - $this->name = _i($id); - $this->title = $title; - $this->urlParams = $urlParams; - $this->isActive = $active; + public function __construct(protected string $id, protected string $title, protected array $urlParams, protected bool $isActive) { + $this->name = _i($this->id); } public function getId(): string { diff --git a/app/Models/Search.php b/app/Models/Search.php index 45fa742be..4a006c2d0 100644 --- a/app/Models/Search.php +++ b/app/Models/Search.php @@ -9,7 +9,7 @@ require_once(LIB_PATH . '/lib_date.php'); * It allows to extract meaningful bits of the search and store them in a * convenient object */ -class FreshRSS_Search { +class FreshRSS_Search implements \Stringable { /** * This contains the user input string diff --git a/app/Models/Share.php b/app/Models/Share.php index 2df9dd4d9..847127466 100644 --- a/app/Models/Share.php +++ b/app/Models/Share.php @@ -68,33 +68,20 @@ class FreshRSS_Share { public static function get(string $type): ?FreshRSS_Share { return self::$list_sharing[$type] ?? null; } - - - private string $type; - private string $name; - private string $url_transform; - /** @var array<callable>|array<string,array<callable>> */ - private array $transforms; + private readonly string $name; /** * @phpstan-var 'simple'|'advanced' */ - private string $form_type; - private string $help_url; + private readonly string $form_type; private ?string $custom_name = null; private ?string $base_url = null; private ?string $id = null; private ?string $title = null; private ?string $link = null; - private bool $isDeprecated; /** * @phpstan-var 'GET'|'POST' */ private string $method; - private ?string $field; - /** - * @phpstan-var 'button'|null - */ - private ?string $HTMLtag; /** * Create a FreshRSS_Share object. @@ -108,15 +95,18 @@ class FreshRSS_Share { * @param 'GET'|'POST' $method defines the sharing method (GET or POST) * @param 'button'|null $HTMLtag */ - private function __construct(string $type, string $url_transform, array $transforms, string $form_type, - string $help_url, string $method, ?string $field, ?string $HTMLtag, bool $isDeprecated = false) { - $this->type = $type; - $this->name = _t('gen.share.' . $type); - $this->url_transform = $url_transform; - $this->help_url = $help_url; - $this->HTMLtag = $HTMLtag; - $this->isDeprecated = $isDeprecated; - $this->transforms = $transforms; + private function __construct( + private readonly string $type, + private readonly string $url_transform, + private array $transforms, + string $form_type, + private readonly string $help_url, + string $method, + private ?string $field, + private readonly ?string $HTMLtag, + private readonly bool $isDeprecated = false + ) { + $this->name = _t('gen.share.' . $this->type); if (!in_array($form_type, ['simple', 'advanced'], true)) { $form_type = 'simple'; @@ -126,7 +116,6 @@ class FreshRSS_Share { $method = 'GET'; } $this->method = $method; - $this->field = $field; } /** diff --git a/app/Models/StatsDAO.php b/app/Models/StatsDAO.php index c9753cf2c..6782bd7ee 100644 --- a/app/Models/StatsDAO.php +++ b/app/Models/StatsDAO.php @@ -147,19 +147,12 @@ SQL; if ($res == false) { return []; } - switch ($period) { - case '%H': - $periodMax = 24; - break; - case '%w': - $periodMax = 7; - break; - case '%m': - $periodMax = 12; - break; - default: - $periodMax = 30; - } + $periodMax = match ($period) { + '%H' => 24, + '%w' => 7, + '%m' => 12, + default => 30, + }; $repartition = array_fill(0, $periodMax, 0); foreach ($res as $value) { diff --git a/app/Models/StatsDAOPGSQL.php b/app/Models/StatsDAOPGSQL.php index ba5cbfca1..5e3476808 100644 --- a/app/Models/StatsDAOPGSQL.php +++ b/app/Models/StatsDAOPGSQL.php @@ -57,19 +57,12 @@ SQL; return []; } - switch ($period) { - case 'hour': - $periodMax = 24; - break; - case 'day': - $periodMax = 7; - break; - case 'month': - $periodMax = 12; - break; - default: - $periodMax = 30; - } + $periodMax = match ($period) { + 'hour' => 24, + 'day' => 7, + 'month' => 12, + default => 30, + }; $repartition = array_fill(0, $periodMax, 0); foreach ($res as $value) { diff --git a/app/Models/StatsDAOSQLite.php b/app/Models/StatsDAOSQLite.php index c45951069..4e51615fc 100644 --- a/app/Models/StatsDAOSQLite.php +++ b/app/Models/StatsDAOSQLite.php @@ -32,19 +32,12 @@ SQL; return []; } - switch ($period) { - case '%H': - $periodMax = 24; - break; - case '%w': - $periodMax = 7; - break; - case '%m': - $periodMax = 12; - break; - default: - $periodMax = 30; - } + $periodMax = match ($period) { + '%H' => 24, + '%w' => 7, + '%m' => 12, + default => 30, + }; $repartition = array_fill(0, $periodMax, 0); foreach ($res as $value) { diff --git a/app/Models/Themes.php b/app/Models/Themes.php index a5167c8e8..2a55a84db 100644 --- a/app/Models/Themes.php +++ b/app/Models/Themes.php @@ -165,14 +165,11 @@ class FreshRSS_Themes extends Minz_Model { } } - switch ($type) { - case self::ICON_URL: - return Minz_Url::display($url); - case self::ICON_IMG: - return '<img class="icon" src="' . Minz_Url::display($url) . '" loading="lazy" alt="' . $alt . '"' . $title . ' />'; - case self::ICON_EMOJI: - default: - return '<span class="icon"' . $title . '>' . $alt . '</span>'; - } + return match ($type) { + self::ICON_URL => Minz_Url::display($url), + self::ICON_IMG => '<img class="icon" src="' . Minz_Url::display($url) . '" loading="lazy" alt="' . $alt . '"' . $title . ' />', + self::ICON_EMOJI, => '<span class="icon"' . $title . '>' . $alt . '</span>', + default => '<span class="icon"' . $title . '>' . $alt . '</span>', + }; } } diff --git a/app/Models/UserQuery.php b/app/Models/UserQuery.php index 1ec8ee148..d3a56bb6a 100644 --- a/app/Models/UserQuery.php +++ b/app/Models/UserQuery.php @@ -8,7 +8,6 @@ declare(strict_types=1); * easy way. */ class FreshRSS_UserQuery { - private bool $deprecated = false; private string $get = ''; private string $get_name = ''; @@ -16,16 +15,12 @@ class FreshRSS_UserQuery { /** XML-encoded name */ private string $name = ''; private string $order = ''; - private FreshRSS_BooleanSearch $search; + private readonly FreshRSS_BooleanSearch $search; private int $state = 0; private string $url = ''; private string $token = ''; private bool $shareRss = false; private bool $shareOpml = false; - /** @var array<int,FreshRSS_Category> $categories */ - private array $categories; - /** @var array<int,FreshRSS_Tag> $labels */ - private array $labels; /** XML-encoded description */ private string $description = ''; private string $imageUrl = ''; @@ -48,9 +43,11 @@ class FreshRSS_UserQuery { * @param array<int,FreshRSS_Category> $categories * @param array<int,FreshRSS_Tag> $labels */ - public function __construct(array $query, array $categories, array $labels) { - $this->categories = $categories; - $this->labels = $labels; + public function __construct( + array $query, + private array $categories, + private array $labels, + ) { if (isset($query['get'])) { $this->parseGet($query['get']); } else { diff --git a/app/Models/View.php b/app/Models/View.php index 3c3b3a2e0..4ce837922 100644 --- a/app/Models/View.php +++ b/app/Models/View.php @@ -12,8 +12,8 @@ class FreshRSS_View extends Minz_View { public $callbackBeforePagination; /** @var array<int,FreshRSS_Category> */ public array $categories; - public ?FreshRSS_Category $category; - public ?FreshRSS_Tag $tag; + public ?FreshRSS_Category $category = null; + public ?FreshRSS_Tag $tag = null; public string $current_user; /** @var iterable<FreshRSS_Entry> */ public $entries; @@ -120,10 +120,10 @@ class FreshRSS_View extends Minz_View { // Extensions /** @var array<array{'name':string,'author':string,'description':string,'version':string,'entrypoint':string,'type':'system'|'user','url':string,'method':string,'directory':string}> */ public array $available_extensions; - public ?Minz_Extension $ext_details; + public ?Minz_Extension $ext_details = null; /** @var array{'system':array<Minz_Extension>,'user':array<Minz_Extension>} */ public array $extension_list; - public ?Minz_Extension $extension; + public ?Minz_Extension $extension = null; /** @var array<string,string> */ public array $extensions_installed; |
