aboutsummaryrefslogtreecommitdiff
path: root/app/Models/Entry.php
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2023-04-14 14:23:45 +0200
committerGravatar GitHub <noreply@github.com> 2023-04-14 14:23:45 +0200
commitb3121709d62d9fadf890e523b9c9dba7cf702d25 (patch)
tree17da25c780ca11a76e0e456584790937cb993203 /app/Models/Entry.php
parent61550b1d2d995896a6bf2ee854e19b6210026674 (diff)
PHPStan Level 6 FreshRSS_Search FreshRSS_Entry (#5292)
* PHPStan Level 6 FreshRSS_Search FreshRSS_Entry * Minor fix * Type fix * Apply suggestions from code review Co-authored-by: Luc SANCHEZ <4697568+ColonelMoutarde@users.noreply.github.com> * Minor types syntax Compatibility Intelephense --------- Co-authored-by: Luc SANCHEZ <4697568+ColonelMoutarde@users.noreply.github.com>
Diffstat (limited to 'app/Models/Entry.php')
-rw-r--r--app/Models/Entry.php172
1 files changed, 96 insertions, 76 deletions
diff --git a/app/Models/Entry.php b/app/Models/Entry.php
index 36c581746..be31387c3 100644
--- a/app/Models/Entry.php
+++ b/app/Models/Entry.php
@@ -7,18 +7,13 @@ class FreshRSS_Entry extends Minz_Model {
const STATE_FAVORITE = 4;
const STATE_NOT_FAVORITE = 8;
- /**
- * @var string
- */
+ /** @var string */
private $id = '0';
-
- /**
- * @var string
- */
+ /** @var string */
private $guid;
-
/** @var string */
private $title;
+ /** @var array<string> */
private $authors;
/** @var string */
private $content;
@@ -26,32 +21,26 @@ class FreshRSS_Entry extends Minz_Model {
private $link;
/** @var int */
private $date;
- private $date_added = 0; //In microseconds
- /**
- * @var string
- */
+ /** @var string In microseconds */
+ private $date_added = '0';
+ /** @var string */
private $hash = '';
- /**
- * @var bool|null
- */
+ /** @var bool|null */
private $is_read;
/** @var bool|null */
private $is_favorite;
-
- /**
- * @var int
- */
+ /** @var int */
private $feedId;
-
- /**
- * @var FreshRSS_Feed|null
- */
+ /** @var FreshRSS_Feed|null */
private $feed;
-
/** @var array<string> */
private $tags = [];
+ /** @var array<string,mixed> */
private $attributes = [];
+ /**
+ * @param int|string $pubdate
+ */
public function __construct(int $feedId = 0, string $guid = '', string $title = '', string $authors = '', string $content = '',
string $link = '', $pubdate = 0, bool $is_read = false, bool $is_favorite = false, string $tags = '') {
$this->_title($title);
@@ -112,10 +101,14 @@ class FreshRSS_Entry extends Minz_Model {
public function title(): string {
return $this->title == '' ? $this->guid() : $this->title;
}
+ /** @deprecated */
public function author(): string {
- //Deprecated
return $this->authors(true);
}
+ /**
+ * @phpstan return ($asString ? string : array<string>)
+ * @return string|array<string>
+ */
public function authors(bool $asString = false) {
if ($asString) {
return $this->authors == null ? '' : ';' . implode('; ', $this->authors);
@@ -131,6 +124,7 @@ class FreshRSS_Entry extends Minz_Model {
return preg_match('/(?P<delim>[\'"])' . preg_quote($link, '/') . '(?P=delim)/', $html) == 1;
}
+ /** @param array{'url'?:string,'length'?:int,'medium'?:string,'type'?:string} $enclosure */
private static function enclosureIsImage(array $enclosure): bool {
$elink = $enclosure['url'] ?? '';
$length = $enclosure['length'] ?? 0;
@@ -226,7 +220,7 @@ HTML;
return $content;
}
- /** @return iterable<array<string,string>> */
+ /** @return iterable<array{'url':string,'type'?:string,'medium'?:string,'length'?:int,'title'?:string,'description'?:string,'credit'?:string,'height'?:int,'width'?:int,'thumbnails'?:array<string>}> */
public function enclosures(bool $searchBodyImages = false) {
$attributeEnclosures = $this->attributes('enclosures');
if (is_array($attributeEnclosures)) {
@@ -245,35 +239,41 @@ HTML;
if ($searchEnclosures) {
// Legacy code for database entries < FreshRSS 1.20.1
$enclosures = $xpath->query('//div[@class="enclosure"]/p[@class="enclosure-content"]/*[@src]');
- foreach ($enclosures as $enclosure) {
- $result = [
- 'url' => $enclosure->getAttribute('src'),
- 'type' => $enclosure->getAttribute('data-type'),
- 'medium' => $enclosure->getAttribute('data-medium'),
- 'length' => $enclosure->getAttribute('data-length'),
- ];
- if (empty($result['medium'])) {
- switch (strtolower($enclosure->nodeName)) {
- case 'img': $result['medium'] = 'image'; break;
- case 'video': $result['medium'] = 'video'; break;
- case 'audio': $result['medium'] = 'audio'; break;
+ if (!empty($enclosures)) {
+ /** @var DOMElement $enclosure */
+ foreach ($enclosures as $enclosure) {
+ $result = [
+ 'url' => $enclosure->getAttribute('src'),
+ 'type' => $enclosure->getAttribute('data-type'),
+ 'medium' => $enclosure->getAttribute('data-medium'),
+ 'length' => (int)($enclosure->getAttribute('data-length')),
+ ];
+ if (empty($result['medium'])) {
+ switch (strtolower($enclosure->nodeName)) {
+ case 'img': $result['medium'] = 'image'; break;
+ case 'video': $result['medium'] = 'video'; break;
+ case 'audio': $result['medium'] = 'audio'; break;
+ }
}
+ yield Minz_Helper::htmlspecialchars_utf8($result);
}
- yield Minz_Helper::htmlspecialchars_utf8($result);
}
}
if ($searchBodyImages) {
$images = $xpath->query('//img');
- foreach ($images as $img) {
- $src = $img->getAttribute('src');
- if ($src == null) {
- $src = $img->getAttribute('data-src');
- }
- if ($src != null) {
- $result = [
- 'url' => $src,
- ];
- yield Minz_Helper::htmlspecialchars_utf8($result);
+ if (!empty($images)) {
+ /** @var DOMElement $img */
+ foreach ($images as $img) {
+ $src = $img->getAttribute('src');
+ if ($src == null) {
+ $src = $img->getAttribute('data-src');
+ }
+ if ($src != null) {
+ $result = [
+ 'url' => $src,
+ ];
+ yield Minz_Helper::htmlspecialchars_utf8($result);
+ }
}
}
}
@@ -304,7 +304,10 @@ HTML;
public function link(): string {
return $this->link;
}
- /** @return string|int */
+ /**
+ * @phpstan-return ($raw is false ? string : int)
+ * @return string|int
+ */
public function date(bool $raw = false) {
if ($raw) {
return $this->date;
@@ -314,6 +317,7 @@ HTML;
public function machineReadableDate(): string {
return @date (DATE_ATOM, $this->date);
}
+ /** @return int|string */
public function dateAdded(bool $raw = false, bool $microsecond = false) {
if ($raw) {
if ($microsecond) {
@@ -326,10 +330,10 @@ HTML;
return timestamptodate($date);
}
}
- public function isRead() {
+ public function isRead(): ?bool {
return $this->is_read;
}
- public function isFavorite() {
+ public function isFavorite(): ?bool {
return $this->is_favorite;
}
@@ -357,7 +361,11 @@ HTML;
}
}
- public function attributes($key = '') {
+ /**
+ * @phpstan-return ($key is non-empty-string ? mixed : array<string,mixed>)
+ * @return array<string,mixed>|mixed
+ */
+ public function attributes(string $key = '') {
if ($key == '') {
return $this->attributes;
} else {
@@ -365,7 +373,8 @@ HTML;
}
}
- public function _attributes(string $key, $value) {
+ /** @param string|array<mixed>|bool|int|null $value */
+ public function _attributes(string $key, $value): void {
if ($key == '') {
if (is_string($value)) {
$value = json_decode($value, true);
@@ -388,7 +397,7 @@ HTML;
return $this->hash;
}
- public function _hash(string $value) {
+ public function _hash(string $value): string {
$value = trim($value);
if (ctype_xdigit($value)) {
$this->hash = substr($value, 0, 32);
@@ -396,13 +405,13 @@ HTML;
return $this->hash;
}
- public function _id($value) {
+ public function _id(string $value): void {
$this->id = $value;
if ($this->date_added == 0) {
$this->date_added = $value;
}
}
- public function _guid(string $value) {
+ public function _guid(string $value): void {
if ($value == '') {
$value = $this->link;
if ($value == '') {
@@ -411,20 +420,21 @@ HTML;
}
$this->guid = $value;
}
- public function _title(string $value) {
+ public function _title(string $value): void {
$this->hash = '';
$this->title = trim($value);
}
- public function _author(string $value) {
- //Deprecated
+ /** @deprecated */
+ public function _author(string $value): void {
$this->_authors($value);
}
- public function _authors($value) {
+ /** @param array<string>|string $value */
+ public function _authors($value): void {
$this->hash = '';
if (!is_array($value)) {
if (strpos($value, ';') !== false) {
$value = htmlspecialchars_decode($value, ENT_QUOTES);
- $value = preg_split('/\s*[;]\s*/', $value, -1, PREG_SPLIT_NO_EMPTY);
+ $value = preg_split('/\s*[;]\s*/', $value, -1, PREG_SPLIT_NO_EMPTY) ?: '';
$value = Minz_Helper::htmlspecialchars_utf8($value);
} else {
$value = preg_split('/\s*[,]\s*/', $value, -1, PREG_SPLIT_NO_EMPTY);
@@ -432,49 +442,51 @@ HTML;
}
$this->authors = $value;
}
- public function _content(string $value) {
+ public function _content(string $value): void {
$this->hash = '';
$this->content = $value;
}
- public function _link(string $value) {
+ public function _link(string $value): void {
$this->hash = '';
$this->link = $value;
}
- public function _date($value) {
+ /** @param int|string $value */
+ public function _date($value): void {
$this->hash = '';
$value = intval($value);
$this->date = $value > 1 ? $value : time();
}
- public function _dateAdded($value, bool $microsecond = false) {
+ /** @param int|string $value */
+ public function _dateAdded($value, bool $microsecond = false): void {
if ($microsecond) {
$this->date_added = $value;
} else {
- $this->date_added = $value * 1000000;
+ $this->date_added = $value . '000000';
}
}
- public function _isRead($value) {
+ public function _isRead(?bool $value): void {
$this->is_read = $value === null ? null : (bool)$value;
}
- public function _isFavorite($value) {
+ public function _isFavorite(?bool $value): void {
$this->is_favorite = $value === null ? null : (bool)$value;
}
- /** @param FreshRSS_Feed|null $feed */
- public function _feed($feed) {
+ public function _feed(?FreshRSS_Feed $feed): void {
$this->feed = $feed;
$this->feedId = $this->feed == null ? 0 : $this->feed->id();
}
/** @param int|string $id */
- private function _feedId($id) {
+ private function _feedId($id): void {
$this->feed = null;
$this->feedId = intval($id);
}
- public function _tags($value) {
+ /** @param array<string>|string $value */
+ public function _tags($value): void {
$this->hash = '';
if (!is_array($value)) {
- $value = preg_split('/\s*[#,]\s*/', $value, -1, PREG_SPLIT_NO_EMPTY);
+ $value = preg_split('/\s*[#,]\s*/', $value, -1, PREG_SPLIT_NO_EMPTY) ?: [];
}
$this->tags = $value;
}
@@ -494,7 +506,13 @@ HTML;
} elseif ($filter instanceof FreshRSS_Search) {
// Searches are combined by OR and are not recursive
$ok = true;
- if ($filter->getMinDate()) {
+ if ($filter->getEntryIds()) {
+ $ok &= in_array($this->id, $filter->getEntryIds());
+ }
+ if ($ok && $filter->getNotEntryIds()) {
+ $ok &= !in_array($this->id, $filter->getNotEntryIds());
+ }
+ if ($ok && $filter->getMinDate()) {
$ok &= strnatcmp($this->id, $filter->getMinDate() . '000000') >= 0;
}
if ($ok && $filter->getNotMinDate()) {
@@ -594,7 +612,8 @@ HTML;
return $ok;
}
- public function applyFilterActions(array $titlesAsRead = []) {
+ /** @param array<string,int> $titlesAsRead */
+ public function applyFilterActions(array $titlesAsRead = []): void {
if ($this->feed != null) {
if ($this->feed->attributes('read_upon_reception') ||
($this->feed->attributes('read_upon_reception') === null && FreshRSS_Context::$user_conf->mark_when['reception'])) {
@@ -741,6 +760,7 @@ HTML;
return false;
}
+ /** @return array{'id':string,'guid':string,'title':string,'author':string,'content':string,'link':string,'date':int,'hash':string,'is_read':?bool,'is_favorite':?bool,'id_feed':int,'tags':string,'attributes':array<string,mixed>} */
public function toArray(): array {
return array(
'id' => $this->id(),