Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
208 lines (173 sloc) 6.75 KB
<?php
/**
* RSS feed generator Paper Rosie 2
*
* @package Propeller
*/
class Rss {
# Константы кодов ошибок
const noChannel = 1001;
const invalidDate = 1002;
const noGuid = 1003;
# Какие случаются ошибки
private $errorMsg = array(
self::noChannel =>'Заданного канала не существует',
self::invalidDate =>'Неверный формат даты',
self::noGuid =>'Невозможно сгенерировать RSS-элемент без guid'
);
/**
* Внутренние переменные
*/
private $channels;
private $encoding;
private $dateFormat = "D, d M Y H:i:s";
private $currentChannel = 0;
private $xmlns = array();
/**
* Конструктор
*/
function __construct($enc = 'utf-8') {
$this->channels = array();
$this->encoding = $enc;
$this->setChannel();
}
/**
* Добавить объявление пространства имён
*
* @param string $ns пространство имён
* @param string $url ссылка на описание
*/
function addNs($ns, $url) {
$this->xmlns[$ns] = $url;
}
/**
* Добавление канала
*
* @param int $num номер канала
* @return int номер канала
*/
function addChannel($title, $url, $description, $language, $editor, $image = null) {
$this->channels[] = array('info'=>array(
'title'=>$title,
'url'=>$url,
'description'=>$description,
'language'=>$language,
'editor'=>$editor,
'image'=>$image),
'items'=>array(), 'maxDate'=>0);
return count($this->channels) - 1;
}
/**
* Смена текузего канала
*
* @param int $num номер канала
*/
function setChannel($num = 0) {
$this->currentChannel = $num;
}
/**
* Добавление записи в текущий канал
*
* @param string $guid идентификатор записи
* @param string $description текст записи
* @param int|string $pubDate время публикации в виде строки или числа
* @param array все остальные любые поля записи
*/
function addItem($guid, $title, $description, $pubDate, $author = null, $link = null, $body = null) {
# Существует ли канал
if(!is_array($this->channels[$this->currentChannel])) throw new Exception($this->errorMsg[self::noChannel], self::noChannel);
if($body && is_array($body)) {
$data = $body;
} else {
$data = array();
}
$data['guid'] = $guid;
if($title) $data['title'] = $title;
if($link) $data['link'] = $link;
if($author) $data['author'] = $author;
$data['description'] = $description;
# Формирование даты
if(is_numeric($pubDate)) {
$data['pubDate'] = gmdate($this->dateFormat, $pubDate) . ' GMT';
$pubDateInt = $pubDate;
} else {
$data['pubDate'] = $pubDate;
$pubDateInt = strtotime($pubDate);
if(!$pubDateInt) throw new Exception($this->errorMsg[self::invalidDate], self::invalidDate);
}
# Ищем время последней публикации
if($this->channels[$this->currentChannel]['maxDate'] < $pubDateInt) $this->channels[$this->currentChannel]['maxDate'] = $pubDateInt;
array_push($this->channels[$this->currentChannel]['items'], $data);
}
/**
* Вывод данных
*/
function display() {
header('Content-Type: text/xml');
echo '<?xml version="1.0" encoding="' . $this->encoding . '"?>' . "\n";
echo '<rss version="2.0"';
if(count($this->xmlns)) foreach($this->xmlns as $ns=>$url) echo " xmlns:" . $ns . '="' . $url . '"';
echo '>' . "\n";
foreach($this->channels as $channel) {
$chanInfo = $channel['info'];
echo "<channel>\n";
if(!empty($chanInfo['title'])) echo '<title><![CDATA[' . $chanInfo['title'] . ']]></title>' . "\n";
if(!empty($chanInfo['url'])) echo '<link>' . $chanInfo['url'] . '</link>' . "\n";
if(!empty($chanInfo['description'])) echo '<description><![CDATA[' . $chanInfo['description'] . ']]></description>' . "\n";
if(!empty($chanInfo['language'])) echo '<language>' . $chanInfo['language'] . '</language>' . "\n";
echo '<pubDate>' . gmdate($this->dateFormat, time()) . ' GMT</pubDate>' . "\n";
echo '<lastBuildDate>' . gmdate($this->dateFormat, $channel['maxDate']) . ' GMT</lastBuildDate>' . "\n";
echo '<generator>Paper Rosie 2.0</generator>' . "\n";
if(!empty($chanInfo['editor'])) echo "<managingEditor><![CDATA[" . $chanInfo['editor'] . "]]></managingEditor>\n";
if(!empty($chanInfo['editor'])) echo "<webMaster><![CDATA[" . $chanInfo['editor'] . "]]></webMaster>\n";
if(!empty($chanInfo['image'])) {
echo '<image>';
echo '<url>' . $chanInfo['image'] . '</url>' . "\n";
if(!empty($chanInfo['url'])) echo '<link>' . $chanInfo['url'] . '</link>' . "\n";
echo '<title><![CDATA[' . $chanInfo['title'] . ']]></title>' . "\n";
echo '</image>' . "\n";
}
foreach($channel['items'] as $item) {
if(empty($item['guid'])) {
throw new Exception($this->errorMsg[self::noGuid], self::noGuid);
}
echo '<item>' . "\n";
echo '<guid>' . $item['guid'] . '</guid>' . "\n";
if(!empty($item['link'])) { echo '<link>' . $item['link'] . '</link>' . "\n"; }
if(!empty($item['title'])) { echo '<title><![CDATA[' . $item['title'] . ']]></title>' . "\n"; }
if(!empty($item['description'])) { echo '<description><![CDATA[' . $item['description'] . ']]></description>' . "\n"; }
if(!empty($item['pubDate'])) { echo '<pubDate>' . $item['pubDate'] . '</pubDate>' . "\n"; }
if(!empty($item['author'])) { echo '<author>' . $item['author'] . '</author>' . "\n"; }
if(!empty($item['custom'])) $this->valueOutput($item['custom']);
echo '</item>' . "\n";
}
echo "</channel>\n";
echo "</rss>\n";
}
}
/**
* Вывод допольнительных полей
*
* @param array $value массив данных
*/
function valueOutput($items) {
foreach($items as $item) {
echo '<' . $item['name'];
if(!empty($item['attributes'])) foreach($item['attributes'] as $name=>$value) echo " $name=" . '"' . str_replace('&', '&amp;', $value) . '"';
if(!empty($item['value'])) {
echo ">";
if(!empty($item['cdata'])) echo '<![CDATA[';
echo $item['value'];
if(!empty($item['cdata'])) echo ']]>';
echo "</" . $item['name'] . ">\n";
} elseif(!empty($item['childs'])) {
echo ">\n";
$this->valueOutput($item['childs']);
echo "</" . $item['name'] . ">\n";
} else {
echo " />\n";
}
}
}
}
?>
Something went wrong with that request. Please try again.