diff --git a/localization/locale_dede.php b/localization/locale_dede.php
index bcf88373d..51b01ba70 100644
--- a/localization/locale_dede.php
+++ b/localization/locale_dede.php
@@ -14,8 +14,7 @@
'timeUnits' => array(
'sg' => ["Jahr", "Monat", "Woche", "Tag", "Stunde", "Minute", "Sekunde", "Millisekunde"],
'pl' => ["Jahre", "Monate", "Wochen", "Tage", "Stunden", "Minuten", "Sekunden", "Millisekunden"],
- 'ab' => ["J.", "M.", "W.", "Tag", "Std.", "Min.", "Sek.", "Ms."],
- 'ago' => 'vor %s'
+ 'ab' => ["J.", "M.", "W.", "Tag", "Std.", "Min.", "Sek.", "Ms."]
),
'main' => array(
'name' => "Name",
@@ -52,6 +51,7 @@
'or' => " oder ",
'back' => "Zurück",
'reputationTip' => "Rufpunkte",
+ 'byUserTimeAgo' => "Von %1s vor %s",
// filter
'extSearch' => "Erweiterte Suche",
diff --git a/localization/locale_enus.php b/localization/locale_enus.php
index 46388f036..876d88cab 100644
--- a/localization/locale_enus.php
+++ b/localization/locale_enus.php
@@ -9,8 +9,7 @@
'timeUnits' => array(
'sg' => ["year", "month", "week", "day", "hour", "minute", "second", "millisecond"],
'pl' => ["years", "months", "weeks", "days", "hours", "minutes", "seconds", "milliseconds"],
- 'ab' => ["yr", "mo", "wk", "day", "hr", "min", "sec", "ms"],
- 'ago' => '%s ago'
+ 'ab' => ["yr", "mo", "wk", "day", "hr", "min", "sec", "ms"]
),
'main' => array(
'name' => "name",
@@ -47,6 +46,7 @@
'or' => " or ",
'back' => "Back",
'reputationTip' => "Reputation points",
+ 'byUserTimeAgo' => "By %1s %s ago",
// filter
'extSearch' => "Extended search",
diff --git a/localization/locale_eses.php b/localization/locale_eses.php
index 653f58d39..7b56d5aa9 100644
--- a/localization/locale_eses.php
+++ b/localization/locale_eses.php
@@ -14,8 +14,7 @@
'timeUnits' => array(
'sg' => ["año", "mes", "semana", "día", "hora", "minuto", "segundo", "milisegundo"],
'pl' => ["años", "meses", "semanas", "dias", "horas", "minutos", "segundos", "milisegundos"],
- 'ab' => ["año", "mes", "sem", "", "h", "min", "seg", "ms"],
- 'ago' => 'hace %s'
+ 'ab' => ["año", "mes", "sem", "", "h", "min", "seg", "ms"]
),
'main' => array(
'name' => "nombre",
@@ -52,6 +51,7 @@
'or' => " o ",
'back' => "Arrière",
'reputationTip' => "Puntos de reputación",
+ 'byUserTimeAgo' => "Por %1s hace %s",
// filter
'extSearch' => "Extender búsqueda",
diff --git a/localization/locale_frfr.php b/localization/locale_frfr.php
index 975b917f8..67941ed44 100644
--- a/localization/locale_frfr.php
+++ b/localization/locale_frfr.php
@@ -14,8 +14,7 @@
'timeUnits' => array(
'sg' => ["année", "mois", "semaine", "jour", "heure", "minute", "seconde", "milliseconde"],
'pl' => ["années", "mois", "semaines", "jours", "heures", "minutes", "secondes", "millisecondes"],
- 'ab' => ["an", "mo", "sem", "jour", "h", "min", "s", "ms"],
- 'ago' => 'il y a %s'
+ 'ab' => ["an", "mo", "sem", "jour", "h", "min", "s", "ms"]
),
'main' => array(
'name' => "nom",
@@ -52,6 +51,7 @@
'or' => " ou ",
'back' => "Redro",
'reputationTip' => "Points de réputation",
+ 'byUserTimeAgo' => "Par %1s il y a %s",
// filter
'extSearch' => "Recherche avancée",
diff --git a/localization/locale_ruru.php b/localization/locale_ruru.php
index 4e0e2d8a4..59867a62c 100644
--- a/localization/locale_ruru.php
+++ b/localization/locale_ruru.php
@@ -14,8 +14,7 @@
'timeUnits' => array(
'sg' => ["год", "месяц", "неделя", "день", "час", "минута", "секунда", "миллисекунда"],
'pl' => ["годы", "месяцы", "недели", "дн.", "часы", "мин", "секунды", "миллисекундах"],
- 'ab' => ["г.", "мес.", "нед.", "дн", "ч.", "мин", "сек.", "мс"],
- 'ago' => '%s назад'
+ 'ab' => ["г.", "мес.", "нед.", "дн", "ч.", "мин", "сек.", "мс"]
),
'main' => array(
'name' => "название",
@@ -52,6 +51,7 @@
'or' => " или ",
'back' => "Назад",
'reputationTip' => "Очки репутации",
+ 'byUserTimeAgo' => "От %1s %s назад",
// filter
'extSearch' => "Расширенный поиск",
diff --git a/pages/utility.php b/pages/utility.php
index dbf6caca7..2ca1d815d 100644
--- a/pages/utility.php
+++ b/pages/utility.php
@@ -16,8 +16,10 @@ class UtilityPage extends GenericPage
'latest-additions', 'latest-articles', 'latest-comments', 'latest-screenshots', 'random',
'unrated-comments', 11 => 'latest-videos', 12 => 'most-comments', 13 => 'missing-screenshots'
);
+
private $page = '';
private $rss = false;
+ private $feedData = [];
public function __construct($pageCall, $pageParam)
{
@@ -44,7 +46,7 @@ public function display($override = '')
{
if ($this->rss) // this should not be cached
{
- header('Content-Type: application/rss+xml; charset=ISO-8859-1');
+ header('Content-Type: application/rss+xml; charset=UTF-8');
die($this->generateRSS());
}
else
@@ -68,31 +70,103 @@ protected function generateContent()
header('Location: ?'.Util::$typeStrings[$type].'='.$typeId, true, 302);
die();
- case 'latest-comments':
- $this->lvTabs[] = array(
- 'file' => 'commentpreview',
- 'data' => CommunityContent::getCommentPreviews(),
- 'params' => []
- );
+ case 'latest-comments': // rss
+ $data = CommunityContent::getCommentPreviews();
+
+ if ($this->rss)
+ {
+ foreach ($data as $d)
+ {
+ // todo (low): preview should be html-formated
+ $this->feedData[] = array(
+ 'title' => [true, [], Util::ucFirst(Lang::game(Util::$typeStrings[$d['type']])).Lang::main('colon').htmlentities($d['subject'])],
+ 'link' => [false, [], HOST_URL.'/?go-to-comment&id='.$d['id']],
+ 'description' => [true, [], htmlentities($d['preview'])."
".sprintf(Lang::main('byUserTimeAgo'), $d['user'], Util::formatTime($d['elapsed'] * 1000, true))],
+ 'pubDate' => [false, [], date(DATE_RSS, time() - $d['elapsed'])],
+ 'guid' => [false, [], HOST_URL.'/?go-to-comment&id='.$d['id']]
+ // 'domain' => [false, [], null]
+ );
+ }
+ }
+ else
+ {
+ $this->lvTabs[] = array(
+ 'file' => 'commentpreview',
+ 'data' => $data,
+ 'params' => []
+ );
+ }
break;
- case 'latest-screenshots':
- $this->lvTabs[] = array(
- 'file' => 'screenshot',
- 'data' => CommunityContent::getScreenshots(),
- 'params' => []
- );
+ case 'latest-screenshots': // rss
+ $data = CommunityContent::getScreenshots();
+
+ if ($this->rss)
+ {
+ foreach ($data as $d)
+ {
+ $desc = '
';
+ if ($d['caption'])
+ $desc .= '
'.$d['caption'];
+ $desc .= "
".sprintf(Lang::main('byUserTimeAgo'), $d['user'], Util::formatTime($d['elapsed'] * 1000, true));
+
+ // enclosure/length => filesize('static/uploads/screenshots/thumb/'.$d['id'].'.jpg') .. always set to this placeholder value though
+ $this->feedData[] = array(
+ 'title' => [true, [], Util::ucFirst(Lang::game(Util::$typeStrings[$d['type']])).Lang::main('colon').htmlentities($d['subject'])],
+ 'link' => [false, [], HOST_URL.'/?'.Util::$typeStrings[$d['type']].'='.$d['typeId'].'#screenshots:id='.$d['id']],
+ 'description' => [true, [], $desc],
+ 'pubDate' => [false, [], date(DATE_RSS, time() - $d['elapsed'])],
+ 'enclosure' => [false, ['url' => STATIC_URL.'/uploads/screenshots/thumb/'.$d['id'].'.jpg', 'length' => 12345, 'type' => 'image/jpeg'], null],
+ 'guid' => [false, [], HOST_URL.'/?'.Util::$typeStrings[$d['type']].'='.$d['typeId'].'#screenshots:id='.$d['id']],
+ // 'domain' => [false, [], live|ptr]
+ );
+ }
+ }
+ else
+ {
+ $this->lvTabs[] = array(
+ 'file' => 'screenshot',
+ 'data' => $data,
+ 'params' => []
+ );
+ }
break;
- case 'latest-videos':
- $this->lvTabs[] = array(
- 'file' => 'video',
- 'data' => CommunityContent::getVideos(),
- 'params' => []
- );
+ case 'latest-videos': // rss
+ $data = CommunityContent::getVideos();
+
+ if ($this->rss)
+ {
+ foreach ($data as $d)
+ {
+ $desc = '
';
+ if ($d['caption'])
+ $desc .= '
'.$d['caption'];
+ $desc .= "
".sprintf(Lang::main('byUserTimeAgo'), $d['user'], Util::formatTime($d['elapsed'] * 1000, true));
+
+ // is enclosure/length .. is this even relevant..?
+ $this->feedData[] = array(
+ 'title' => [true, [], Util::ucFirst(Lang::game(Util::$typeStrings[$d['type']])).Lang::main('colon').htmlentities($row['subject'])],
+ 'link' => [false, [], HOST_URL.'/?'.Util::$typeStrings[$d['type']].'='.$d['typeId'].'#videos:id='.$d['id']],
+ 'description' => [true, [], $desc],
+ 'pubDate' => [false, [], date(DATE_RSS, time() - $row['elapsed'])],
+ 'enclosure' => [false, ['url' => '//i3.ytimg.com/vi/'.$d['videoId'].'/default.jpg', 'length' => 12345, 'type' => 'image/jpeg'], null],
+ 'guid' => [false, [], HOST_URL.'/?'.Util::$typeStrings[$d['type']].'='.$d['typeId'].'#videos:id='.$d['id']],
+ // 'domain' => [false, [], live|ptr]
+ );
+ }
+ }
+ else
+ {
+ $this->lvTabs[] = array(
+ 'file' => 'video',
+ 'data' => $data,
+ 'params' => []
+ );
+ }
break;
- case 'latest-articles':
+ case 'latest-articles': // rss
$this->lvTabs = [];
break;
- case 'latest-additions':
+ case 'latest-additions': // rss
$extraText = '';
break;
case 'unrated-comments':
@@ -125,7 +199,7 @@ protected function generateContent()
}
}
break;
- case 'most-comments':
+ case 'most-comments': // rss
if ($this->category && !in_array($this->category[0], [1, 7, 30]))
header('Location: ?most-comments=1'.($this->rss ? '&rss' : null), true, 302);
@@ -155,23 +229,39 @@ protected function generateContent()
if (!$typeClass->error)
{
$data = $typeClass->getListviewData();
- foreach ($data as $typeId => &$d)
- $d['ncomments'] = $comments[$typeId];
- $this->extendGlobalData($typeClass->getJSGlobals(GLOBALINFO_ANY));
- $this->lvTabs[] = array(
- 'file' => $typeClass::$brickFile,
- 'data' => $data,
- 'params' => $params,
- '_type' => Util::$typeStrings[$type]
- );
+ if ($this->rss)
+ {
+ foreach ($data as $typeId => &$d)
+ {
+ $this->feedData[] = array(
+ 'title' => [true, [], htmlentities(Util::$typeStrings[$type] == 'item' ? substr($d['name'], 1) : $d['name'])],
+ 'type' => [false, [], Util::$typeStrings[$type]],
+ 'link' => [false, [], HOST_URL.'/?'.Util::$typeStrings[$type].'='.$d['id']],
+ 'ncomments' => [false, [], $comments[$typeId]['ncomments']]
+ );
+ }
+ }
+ else
+ {
+ foreach ($data as $typeId => &$d)
+ $d['ncomments'] = $comments[$typeId]['ncomments'];
+
+ $this->extendGlobalData($typeClass->getJSGlobals(GLOBALINFO_ANY));
+ $this->lvTabs[] = array(
+ 'file' => $typeClass::$brickFile,
+ 'data' => $data,
+ 'params' => $params
+ );
+ }
}
}
+
break;
}
// found nothing => set empty content
- if (!$this->lvTabs)
+ if (!$this->lvTabs && !$this->rss)
{
$this->lvTabs[] = array(
'file' => 'commentpreview', // anything, doesn't matter what
@@ -185,49 +275,35 @@ protected function generateRSS()
{
$this->generateContent();
- $xml = "\n".
- "\n\n".
- "".CFG_NAME_SHORT.' - '.$this->name."\n".
- "".HOST_URL.'?'.$this->page . ($this->category ? '='.$this->category[0] : null)."\n".
- "".CFG_NAME."\n".
- "".implode('-', str_split(User::$localeString, 2))."\n".
- "".CFG_TTL_RSS."\n".
- "".date(DATE_RSS)."\n";
+ $root = new SimpleXML('');
+ $root->addAttribute('version', '2.0');
+ $channel = $root->addChild('channel');
- if ($this->page == 'most-comments')
- {
- foreach ($this->lvTabs as $tab)
- {
- foreach ($tab['data'] as $row)
- {
- $xml .= "- \n".
- "\n".
- "".$tab['_type']."\n".
- "".HOST_URL.'/?'.$tab['_type'].'='.$row['id']."\n".
- "".$row['ncomments']."\n".
- "
\n";
- }
- }
- }
- else
+ $channel->addChild('title', CFG_NAME_SHORT.' - '.$this->name);
+ $channel->addChild('link', HOST_URL.'/?'.$this->page . ($this->category ? '='.$this->category[0] : null));
+ $channel->addChild('description', CFG_NAME);
+ $channel->addChild('language', implode('-', str_split(User::$localeString, 2)));
+ $channel->addChild('ttl', CFG_TTL_RSS);
+ $channel->addChild('lastBuildDate', date(DATE_RSS));
+
+ foreach ($this->feedData as $row)
{
- foreach ($this->lvTabs[0]['data'] as $row)
+ $item = $channel->addChild('item');
+
+ foreach ($row as $key => list($isCData, $attrib, $text))
{
- $xml .= "- \n".
- "\n".
- "".HOST_URL.'?go-to-comment&id='.$row['id']."\n".
- "\n". // todo (low): preview should be html-formated
- "".date(DATE_RSS, time() - $row['elapsed'])."\n".
- "".HOST_URL.'?go-to-comment&id='.$row['id']."\n".
- "\n".
- "
\n";
+ if ($isCData && $text)
+ $child = $item->addChild($key)->addCData($text);
+ else
+ $child = $item->addChild($key, $text);
+
+ foreach ($attrib as $k => $v)
+ $child->addAttribute($k, $v);
}
}
- $xml .= "\n";
-
- return $xml;
+ return $root->asXML();
}
protected function generateTitle()