206 lines
7.0 KiB
PHP
206 lines
7.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
class EpicGamesStoreNewsBridge extends BridgeAbstract
|
|
{
|
|
const MAINTAINER = 'Akamaru';
|
|
const NAME = 'Epic Games Store News';
|
|
const URI = 'https://store.epicgames.com/news';
|
|
const CACHE_TIMEOUT = 3600; // 1 hour
|
|
const DESCRIPTION = 'Get the latest news from Epic Games Store';
|
|
|
|
const PARAMETERS = array(
|
|
array(
|
|
'lang' => array(
|
|
'name' => 'Language',
|
|
'type' => 'list',
|
|
'values' => array(
|
|
'Bahasa Indonesia' => 'id',
|
|
'Bahasa Melayu' => 'ms',
|
|
'Dansk' => 'da',
|
|
'Deutsch' => 'de',
|
|
'English' => 'en-US',
|
|
'Español' => 'es-ES',
|
|
'Español (Latam)' => 'es-MX',
|
|
'Filipino' => 'fil',
|
|
'Français' => 'fr',
|
|
'Italiano' => 'it',
|
|
'Magyar' => 'hu',
|
|
'Nederlands' => 'nl',
|
|
'Norsk' => 'no',
|
|
'Polski' => 'pl',
|
|
'Português (Brasil)' => 'pt-BR',
|
|
'Português Europeu' => 'pt',
|
|
'Română' => 'ro',
|
|
'Suomi' => 'fi',
|
|
'Svenska' => 'sv',
|
|
'Tiếng Việt' => 'vi',
|
|
'Türkçe' => 'tr',
|
|
'Čeština' => 'cs',
|
|
'Български' => 'bg',
|
|
'Русский' => 'ru',
|
|
'Українська' => 'uk',
|
|
'العربية' => 'ar',
|
|
'हिन्दी' => 'hi',
|
|
'ไทย' => 'th',
|
|
'日本語' => 'ja',
|
|
'简体中文' => 'zh-CN',
|
|
'繁體中文' => 'zh-Hant',
|
|
'한국어' => 'ko',
|
|
),
|
|
'required' => true,
|
|
'defaultValue' => 'en-US'
|
|
),
|
|
'limit' => array(
|
|
'name' => 'Limit (non-sticky news)',
|
|
'type' => 'number',
|
|
'required' => false,
|
|
'defaultValue' => 20
|
|
)
|
|
)
|
|
);
|
|
|
|
public function getIcon()
|
|
{
|
|
return 'https://www.google.com/s2/favicons?domain=store.epicgames.com&sz=32';
|
|
}
|
|
|
|
public function getURI()
|
|
{
|
|
$lang = $this->getInput('lang');
|
|
if (!empty($lang)) {
|
|
return 'https://store.epicgames.com/' . $lang . '/news';
|
|
}
|
|
return self::URI;
|
|
}
|
|
|
|
public function collectData()
|
|
{
|
|
$lang = $this->getInput('lang');
|
|
if (empty($lang)) {
|
|
returnClientError('Language is required');
|
|
}
|
|
|
|
$limit = $this->getInput('limit');
|
|
if (empty($limit)) {
|
|
$limit = 20;
|
|
}
|
|
|
|
// Fetch sticky news
|
|
$stickyUrl = 'https://store-content.ak.epicgames.com/api/' . $lang . '/content/blog/sticky';
|
|
$stickyJson = getContents($stickyUrl);
|
|
$stickyData = json_decode($stickyJson, true);
|
|
|
|
// Fetch regular news
|
|
$regularUrl = 'https://store-content.ak.epicgames.com/api/' . $lang . '/content/blog?limit=' . $limit;
|
|
$regularJson = getContents($regularUrl);
|
|
$regularData = json_decode($regularJson, true);
|
|
|
|
// Combine both arrays, sticky news first
|
|
$allNews = array_merge($stickyData ?? [], $regularData ?? []);
|
|
|
|
foreach ($allNews as $article) {
|
|
$item = array();
|
|
|
|
// Build URL
|
|
$item['uri'] = 'https://store.epicgames.com' . $article['urlPattern'];
|
|
|
|
// Title
|
|
$item['title'] = $article['title'];
|
|
|
|
// Timestamp
|
|
if (isset($article['date'])) {
|
|
$item['timestamp'] = strtotime($article['date']);
|
|
} elseif (isset($article['lastModified'])) {
|
|
$item['timestamp'] = strtotime($article['lastModified']);
|
|
}
|
|
|
|
// Author - clean up suffix like ", Autor" or ", Autorin"
|
|
if (isset($article['author'])) {
|
|
$item['author'] = $this->cleanAuthorName($article['author']);
|
|
}
|
|
|
|
// Content
|
|
if (isset($article['short'])) {
|
|
$item['content'] = $article['short'];
|
|
}
|
|
|
|
// Add full content if available
|
|
if (isset($article['content'])) {
|
|
$item['content'] = $article['content'];
|
|
}
|
|
|
|
// Categories
|
|
if (isset($article['cat'])) {
|
|
$item['categories'] = array($article['cat']);
|
|
}
|
|
|
|
// Enclosures (images)
|
|
if (isset($article['trendingImage'])) {
|
|
$item['enclosures'] = array($article['trendingImage']);
|
|
} elseif (isset($article['_images_']) && is_array($article['_images_']) && count($article['_images_']) > 0) {
|
|
$item['enclosures'] = array($article['_images_'][0]);
|
|
}
|
|
|
|
$this->items[] = $item;
|
|
}
|
|
|
|
// Sort items by timestamp (newest first)
|
|
usort($this->items, function ($a, $b) {
|
|
$timeA = $a['timestamp'] ?? 0;
|
|
$timeB = $b['timestamp'] ?? 0;
|
|
return $timeB - $timeA; // Descending order (newest first)
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Clean author name by removing common suffixes and prefixes like ", Autor", ", Autorin", "寄稿者:", etc.
|
|
* This is a best-effort approach as different languages have different patterns.
|
|
*/
|
|
private function cleanAuthorName($author)
|
|
{
|
|
// Trim whitespace first
|
|
$author = trim($author);
|
|
|
|
// Common suffix patterns in different languages
|
|
$suffixPatterns = array(
|
|
', Contributor', // English
|
|
', contributeur', // French
|
|
', colaborador', // Spanish/Portuguese
|
|
', collaboratore', // Italian
|
|
', Autor', // German (masculine)
|
|
', Autorin', // German (feminine)
|
|
', Author', // English (alternative)
|
|
', Auteur', // French (alternative)
|
|
', Autore', // Italian (alternative)
|
|
', Autora', // Spanish/Portuguese (feminine)
|
|
', Escritor', // Spanish
|
|
', Escritora', // Spanish (feminine)
|
|
', 기고자', // Korean
|
|
', Συγγραφέας', // Greek
|
|
);
|
|
|
|
// Common prefix patterns (mainly Asian languages)
|
|
$prefixPatterns = array(
|
|
'寄稿者:', // Japanese (Contributor:)
|
|
);
|
|
|
|
// Remove suffix patterns
|
|
foreach ($suffixPatterns as $pattern) {
|
|
if (str_ends_with($author, $pattern)) {
|
|
return trim(substr($author, 0, -strlen($pattern)));
|
|
}
|
|
}
|
|
|
|
// Remove prefix patterns
|
|
foreach ($prefixPatterns as $pattern) {
|
|
if (str_starts_with($author, $pattern)) {
|
|
return trim(substr($author, strlen($pattern)));
|
|
}
|
|
}
|
|
|
|
return $author;
|
|
}
|
|
}
|