diff --git a/include/layout.inc b/include/layout.inc index f065310020..857128d64c 100644 --- a/include/layout.inc +++ b/include/layout.inc @@ -542,7 +542,7 @@ function get_news_changes() return false; } - $date = date_create($lastNews["updated"]); + $date = date_create($lastNews["updated"] ?? $lastNews["published"]); if (isset($_COOKIE["LAST_NEWS"]) && $_COOKIE["LAST_NEWS"] >= $date->getTimestamp()) { return false; } @@ -557,6 +557,8 @@ function get_news_changes() $date->modify("+1 week"); if ($date->getTimestamp() > $_SERVER["REQUEST_TIME"]) { + assert(isset($lastNews["link"][0]["href"])); + $link = preg_replace('~^(http://php.net/|https://www.php.net/)~', '/', $lastNews["link"][0]["href"]); $title = $lastNews["title"]; return "{$title}"; diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index eba441413e..ed6401d99c 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2532,24 +2532,6 @@ parameters: count: 1 path: src/News/Entry.php - - - message: '#^Call to function is_array\(\) with null will always evaluate to false\.$#' - identifier: function.impossibleType - count: 1 - path: src/News/NewsHandler.php - - - - message: '#^Method phpweb\\News\\NewsHandler\:\:getLastestNews\(\) return type has no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: src/News/NewsHandler.php - - - - message: '#^Method phpweb\\News\\NewsHandler\:\:getPregeneratedNews\(\) return type has no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: src/News/NewsHandler.php - - message: '#^Method phpweb\\Themes\\FeatureComparison\:\:__construct\(\) has parameter \$links with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue diff --git a/public/index.php b/public/index.php index 6758a83781..1694e3a246 100644 --- a/public/index.php +++ b/public/index.php @@ -61,7 +61,7 @@ foreach ((new NewsHandler())->getFrontPageNews() as $entry) { $link = preg_replace('~^(http://php.net/|https://www.php.net/)~', '', $entry["id"]); $id = parse_url($entry["id"], PHP_URL_FRAGMENT); - $date = date_create($entry['updated']); + $date = date_create($entry['updated'] ?? $entry['published']); $date_human = date_format($date, 'd M Y'); $date_w3c = date_format($date, DATE_W3C); $content .= <<, + * category: list, + * newsImage?: array{ + * link: string, + * content: string, + * }, + * content: string, + * intro?: string, + * finalTeaserDate?: string, + * } + */ final class NewsHandler { private const MAX_FRONT_PAGE_NEWS = 25; + /** + * @return NewsEntryStruct|null + */ public function getLastestNews(): array|null { $news = $this->getPregeneratedNews(); @@ -24,45 +51,48 @@ public function getLastestNews(): array|null return $news[0]; } - /** @return list */ - public function getFrontPageNews(): array + /** + * @param list $tags + * @return list + */ + public function getTaggedEntries(array $tags, ?int $limit = null): array { - $frontPage = []; + $entries = []; foreach ($this->getPregeneratedNews() as $entry) { - foreach ($entry['category'] as $category) { - if ($category['term'] !== 'frontpage') { - continue; - } - - $frontPage[] = $entry; - if (count($frontPage) >= self::MAX_FRONT_PAGE_NEWS) { - break 2; - } + if (!self::isTagged($entry, $tags)) { + continue; + } + + $entries[] = $entry; + if ($limit !== null && count($entries) >= $limit) { + break; } } - return $frontPage; + return $entries; } - /** @return list */ - public function getConferences(): array + /** + * Looks up generated news with frontpage tags. + * + * @return list + */ + public function getFrontPageNews(int $limit = self::MAX_FRONT_PAGE_NEWS): array { - $conferences = []; - foreach ($this->getPregeneratedNews() as $entry) { - foreach ($entry['category'] as $category) { - if ($category['term'] !== 'cfp' && $category['term'] !== 'conferences') { - continue; - } - - $conferences[] = $entry; - break; - } - } + return $this->getTaggedEntries(['frontpage'], $limit); + } - return $conferences; + /** + * @return list + */ + public function getConferences(?int $limit = null): array + { + return $this->getTaggedEntries(['cfp', 'conferences'], $limit); } - /** @return list */ + /** + * @return list + */ public function getNewsByYear(int $year): array { return array_values(array_filter( @@ -71,11 +101,32 @@ public function getNewsByYear(int $year): array )); } + /** + * @return list + */ public function getPregeneratedNews(): array { $NEWS_ENTRIES = null; include __DIR__ . '/../../include/pregen-news.inc'; + /** @phpstan-ignore-next-line - pregen-news sets global variable */ return is_array($NEWS_ENTRIES) ? $NEWS_ENTRIES : []; } + + /** + * @param NewsEntryStruct $data + * @param list|string $tags + */ + public static function isTagged(array $data, array|string $tags): bool + { + $tags = is_array($tags) ? $tags : [$tags]; + + foreach ($data['category'] as $category) { + if (in_array($category['term'], $tags, true)) { + return true; + } + } + + return false; + } }