Skip to content

Commit 9bacc2a

Browse files
committed
Merge remote-tracking branch 'refs/remotes/personal/phpstan-news-types' into refresh-homepage
# Conflicts: # public/index.php
2 parents 3c4e2be + 443d413 commit 9bacc2a

3 files changed

Lines changed: 83 additions & 48 deletions

File tree

include/layout.inc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ function get_news_changes()
542542
return false;
543543
}
544544

545-
$date = date_create($lastNews["updated"]);
545+
$date = date_create($lastNews["updated"] ?? $lastNews["published"]);
546546
if (isset($_COOKIE["LAST_NEWS"]) && $_COOKIE["LAST_NEWS"] >= $date->getTimestamp()) {
547547
return false;
548548
}
@@ -557,6 +557,8 @@ function get_news_changes()
557557

558558
$date->modify("+1 week");
559559
if ($date->getTimestamp() > $_SERVER["REQUEST_TIME"]) {
560+
assert(isset($lastNews["link"][0]["href"]));
561+
560562
$link = preg_replace('~^(http://php.net/|https://www.php.net/)~', '/', $lastNews["link"][0]["href"]);
561563
$title = $lastNews["title"];
562564
return "<a href='{$link}'>{$title}</a>";

phpstan-baseline.neon

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2526,24 +2526,6 @@ parameters:
25262526
count: 1
25272527
path: src/News/Entry.php
25282528

2529-
-
2530-
message: '#^Call to function is_array\(\) with null will always evaluate to false\.$#'
2531-
identifier: function.impossibleType
2532-
count: 1
2533-
path: src/News/NewsHandler.php
2534-
2535-
-
2536-
message: '#^Method phpweb\\News\\NewsHandler\:\:getLastestNews\(\) return type has no value type specified in iterable type array\.$#'
2537-
identifier: missingType.iterableValue
2538-
count: 1
2539-
path: src/News/NewsHandler.php
2540-
2541-
-
2542-
message: '#^Method phpweb\\News\\NewsHandler\:\:getPregeneratedNews\(\) return type has no value type specified in iterable type array\.$#'
2543-
identifier: missingType.iterableValue
2544-
count: 1
2545-
path: src/News/NewsHandler.php
2546-
25472529
-
25482530
message: '#^Method phpweb\\Themes\\FeatureComparison\:\:__construct\(\) has parameter \$links with no value type specified in iterable type array\.$#'
25492531
identifier: missingType.iterableValue

src/News/NewsHandler.php

Lines changed: 80 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,42 @@
55
namespace phpweb\News;
66

77
use DateTimeImmutable;
8-
98
use function array_filter;
109
use function array_values;
10+
use function count;
1111
use function is_array;
1212

13+
/**
14+
* @phpstan-type NewsEntryStruct array{
15+
* title: string,
16+
* id: string,
17+
* published: string,
18+
* updated?: string,
19+
* link?: list<array{
20+
* href: string,
21+
* rel: string,
22+
* type?: string,
23+
* }>,
24+
* category: list<array{
25+
* term: string,
26+
* label: string,
27+
* }>,
28+
* newsImage?: array{
29+
* link: string,
30+
* content: string,
31+
* },
32+
* content: string,
33+
* intro?: string,
34+
* finalTeaserDate?: string,
35+
* }
36+
*/
1337
final class NewsHandler
1438
{
1539
private const MAX_FRONT_PAGE_NEWS = 25;
1640

41+
/**
42+
* @return NewsEntryStruct|null
43+
*/
1744
public function getLastestNews(): array|null
1845
{
1946
$news = $this->getPregeneratedNews();
@@ -24,45 +51,48 @@ public function getLastestNews(): array|null
2451
return $news[0];
2552
}
2653

27-
/** @return list<array> */
28-
public function getFrontPageNews(): array
54+
/**
55+
* @param list<string> $tags
56+
* @return list<NewsEntryStruct>
57+
*/
58+
public function getTaggedEntries(array $tags, ?int $limit = null): array
2959
{
30-
$frontPage = [];
60+
$entries = [];
3161
foreach ($this->getPregeneratedNews() as $entry) {
32-
foreach ($entry['category'] as $category) {
33-
if ($category['term'] !== 'frontpage') {
34-
continue;
35-
}
36-
37-
$frontPage[] = $entry;
38-
if (count($frontPage) >= self::MAX_FRONT_PAGE_NEWS) {
39-
break 2;
40-
}
62+
if (!self::isTagged($entry, $tags)) {
63+
continue;
64+
}
65+
66+
$entries[] = $entry;
67+
if ($limit !== null && count($entries) >= $limit) {
68+
break;
4169
}
4270
}
4371

44-
return $frontPage;
72+
return $entries;
4573
}
4674

47-
/** @return list<array> */
48-
public function getConferences(): array
75+
/**
76+
* Looks up generated news with frontpage tags.
77+
*
78+
* @return list<NewsEntryStruct>
79+
*/
80+
public function getFrontPageNews(int $limit = self::MAX_FRONT_PAGE_NEWS): array
4981
{
50-
$conferences = [];
51-
foreach ($this->getPregeneratedNews() as $entry) {
52-
foreach ($entry['category'] as $category) {
53-
if ($category['term'] !== 'cfp' && $category['term'] !== 'conferences') {
54-
continue;
55-
}
56-
57-
$conferences[] = $entry;
58-
break;
59-
}
60-
}
82+
return $this->getTaggedEntries(['frontpage'], $limit);
83+
}
6184

62-
return $conferences;
85+
/**
86+
* @return list<NewsEntryStruct>
87+
*/
88+
public function getConferences(?int $limit = null): array
89+
{
90+
return $this->getTaggedEntries(['cfp', 'conferences'], $limit);
6391
}
6492

65-
/** @return list<array> */
93+
/**
94+
* @return list<NewsEntryStruct>
95+
*/
6696
public function getNewsByYear(int $year): array
6797
{
6898
return array_values(array_filter(
@@ -71,11 +101,32 @@ public function getNewsByYear(int $year): array
71101
));
72102
}
73103

104+
/**
105+
* @return list<NewsEntryStruct>
106+
*/
74107
public function getPregeneratedNews(): array
75108
{
76109
$NEWS_ENTRIES = null;
77110
include __DIR__ . '/../../include/pregen-news.inc';
78111

112+
/** @phpstan-ignore-next-line - pregen-news sets global variable */
79113
return is_array($NEWS_ENTRIES) ? $NEWS_ENTRIES : [];
80114
}
115+
116+
/**
117+
* @param NewsEntryStruct $data
118+
* @param list<string>|string $tags
119+
*/
120+
public static function isTagged(array $data, array|string $tags): bool
121+
{
122+
$tags = is_array($tags) ? $tags : [$tags];
123+
124+
foreach ($data['category'] as $category) {
125+
if (in_array($category['term'], $tags, true)) {
126+
return true;
127+
}
128+
}
129+
130+
return false;
131+
}
81132
}

0 commit comments

Comments
 (0)