Scripts
RSS Feed Generator
Alweer? Ja alweer, maar deze keer als uitbreiding op PHP DOM. Bekijk het script: http://php.n3rd.nl/index.php/source/rssfeed.php Download het script: http://php.n3rd.nl/index.php/download/rssfeed.php Deze RSS Feed Generator is door zowel mensen die een eenvoudige feed, als door mensen die een uitgebreide feed op hun site willen te gebruiken. Ik heb de generator geschreven aan de hand van de specificaties op http://www.rssboard.org/rss-specification en de W3 feed validator op http://validator.w3.org/feed/ en heb deze voorzien van alle standaard elementen. De generator is geschreven als uitbreiding op de in PHP5 ingebouwde DOM functies. Om te beginnen een eenvoudig voorbeeld:
rss-feed-generator
<?php
/**
* Build a RSS Feed folowing the RSS 2.0.10 specification at:
* http://www.rssboard.org/rss-specification
*
* @author Boaz den Besten
* @copyright GNU/GPL
* @version @version@
*/
class RssFeed extends DOMDocument {
/**
* Create a rss feed
*
* @param String $title The name of the channel. It's how people refer to your service. If you have an HTML website that contains the same information as your RSS file, the title of your channel should be the same as the title of your website.
* @param String $link The URL to the HTML website corresponding to the channel.
* @param String $description Phrase or sentence describing the channel.
*/
public function __construct($title, $link, $description){
parent::__construct();
$root = $this->appendChild($this->createElement('rss'));
$root->setAttribute('version', '2.0');
$channel = $root->appendChild($this->createElement('channel'));
$channel->appendChild(new DOMElement('title', $title));
$channel->appendChild(new DOMElement('description', $description));
if(!filter_var($link, FILTER_VALIDATE_URL)) {
throw new RssFeedException($link.' is not a valid url.');
}
$channel->appendChild(new DOMElement('link', $link));
}
/**
* The language the channel is written in.
*
* @param String $language
*/
public function setLanguage($language){
if(!filter_var($language, FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => '#^([a-z]{2,3}|[a-z]{2}-[a-z]{2})$#')))) {
throw new RssFeedException($language.' is not a valid RSS Language Code.');
}
$this->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('language', $language));
}
/**
* Copyright notice for content in the channel.
*
* @param String $copyright
*/
public function setCopyright($copyright){
$this->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('copyright', $copyright));
}
/**
* Email address for person responsible for technical issues relating to channel.
*
* @param String $webmaster
*/
public function setWebMaster($webmaster){
$this->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('webMaster', $webmaster));
}
/**
* The last time the content of the channel changed.
*
* @param DateTime $lastBuildDate
*/
public function setLastBuildDate(DateTime $lastBuildDate=null){
$this->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('lastBuildDate', $lastBuildDate->format(DATE_RSS)));
}
/**
* Email address for person responsible for editorial content.
*
* @param String $managingEditor
*/
public function setManagingEditor($managingEditor){
$this->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('managingEditor', $managingEditor));
}
/**
* The publication date for the content in the channel.
*
* @param DateTime $pubDate
*/
public function setPubDate(DateTime $pubDate){
$this->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('pubDate', $pubDate->format(DATE_RSS)));
}
/**
* Specify one or more categories that the channel belongs to.
*
* @param String $category
* @param String $domain
*/
public function setCategory($category, $domain=null) {
$category = $this->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('category', $category));
if(!is_null($domain)) {
$category->setAttribute('domain', $domain);
}
}
/**
* A string indicating the program used to generate the channel.
*
* @param String $generator
*/
public function setGenerator($generator){
$this->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('generator', $generator));
}
/**
* A URL that points to the documentation for the format used in the RSS file.
*
* @param String $docs
*/
public function setDocs($docs) {
if(!filter_var($docs, FILTER_VALIDATE_URL)) {
throw new RssFeedException($docs.' is not a valid url.');
}
$this->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('docs', $docs));
}
/**
* Allows processes to register with a cloud to be notified of updates to the channel, implementing a lightweight publish-subscribe protocol for RSS feeds.
*
* @param String $domain
* @param String $port
* @param String $path
* @param String $registerProcedure
* @param String $protocol
*/
public function setCloud($domain, $port, $path, $registerProcedure, $protocol) {
$cloud = $this->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('cloud'));
$cloud->setAttribute('domain', $domain);
$cloud->setAttribute('port', $port);
$cloud->setAttribute('path', $path);
$cloud->setAttribute('registerProcedure', $registerProcedure);
$cloud->setAttribute('protocol', $protocol);
}
/**
* ttl stands for time to live. It's a number of minutes that indicates how long a channel can be cached before refreshing from the source.
*
* @param Integer $ttl
*/
public function setTtl($ttl){
if(!is_integer($ttl)) {
throw new RssFeedException($ttl.' is not a valid integer.');
}
$this->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('ttl', $ttl));
}
/**
* Specifies a GIF, JPEG or PNG image that can be displayed with the channel.
*
* @param String $url
* @param Integer $width
* @param Integer $height
* @param String $description
*/
public function setImage($url, $width=null, $height=null, $description=null) {
if(!filter_var($url, FILTER_VALIDATE_URL) || !filter_var($url, FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => '#\.(jpg|jpeg|png|gif)$#')))) {
throw new RssFeedException($url.' is not a proper image url. (only jpeg, png and gif are supported.)');
}
$image = $this->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('image'));
$image->appendChild(new DOMElement('url', $url));
$image->appendChild(new DOMElement('title', $this->getElementsByTagName('title')->item(0)->nodeValue));
$image->appendChild(new DOMElement('link', $this->getElementsByTagName('link')->item(0)->nodeValue));
if(!is_null($width) && is_integer($width)) {
$image->appendChild(new DOMElement('width', $width));
}
if(!is_null($height) && is_integer($height)) {
$image->appendChild(new DOMElement('height', $height));
}
if(!is_null($description)) {
$image->appendChild(new DOMElement('description', $description));
}
}
/**
* The PICS rating for the channel.
*
* @param String $rating
*/
public function setRating($rating){
$this->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('rating', $rating));
}
/**
* Specifies a text input box that can be displayed with the channel.
*
* @param String $title
* @param String $description
* @param String $name
* @param String $link
*/
public function setTextInput($title, $description, $name, $link) {
if(!filter_var($link, FILTER_VALIDATE_URL)) {
throw new RssFeedException($link.' is not a proper url.');
}
$textInput = $this->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('textInput'));
$textInput->appendChild(new DOMElement('title', $title));
$textInput->appendChild(new DOMElement('description', $description));
$textInput->appendChild(new DOMElement('name', $name));
$textInput->appendChild(new DOMElement('link', $link));
}
/**
* A hint for aggregators telling them which hours they can skip.
*
* @param Array<Integer> $skipHours
*/
public function setSkipHours($skipHours) {
if(!is_array($skipHours) || count($skipHours) > 24) {
throw new RssFeedException('setSkipHours expect an array with 24 elements max.');
}
$skipHoursEl = $this->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('skipHours'));
foreach($skipHours as $skipHour) {
if(!filter_var($skipHour, FILTER_VALIDATE_INT, array('options' => array('min_range' => 0, 'max_range' => 23)))) {
throw new RssFeedException('each skipHours array element sould be an integer between 0 and 23 (hour GMT).');
}
$skipHoursEl->appendChild(new DOMElement('hour', $skipHour));
}
}
/**
* A hint for aggregators telling them which days they can skip.
*
* @param Array<String> $skipDays
*/
public function setSkipDays($skipDays) {
if(!is_array($skipDays) || count($skipDays) > 7) {
throw new RssFeedException('setSkipDays expect an array with 7 elements max.');
}
$skipDaysEl = $this->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('skipDays'));
foreach($skipDays as $skipDay) {
if(!filter_var($skipDay, FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => '#^(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)$#')))) {
throw new RssFeedException('each skipDays array element sould be an String with the english name of a day starting with a capital.');
}
$skipDaysEl->appendChild(new DOMElement('day', $skipDay));
}
}
/**
* Creates an ads a new instance of RssFeedItem to the RssFeed
*
* @return RssFeedItem
*/
public function createFeedItem() {
return $this->getElementsByTagName('channel')->item(0)->appendChild(new RssFeedItem());
}
}
/**
* A Rss Feed item-element folowing the RSS 2.0.10 specification at:
* http://www.rssboard.org/rss-specification
*
* @author Boaz den Besten
* @copyright GNU/GPL
* @version @version@
*/
class RssFeedItem extends DOMElement {
/**
* Create a new RssFeedItem
*
* If u use this constructor a readonly RssFeedItem will becreated,
* use RssFeed::createFeedItem to create and add a new item to the feed.
*/
public function __construct() {
parent::__construct('item');
}
/**
* The title of the item.
*
* @param String $title
*/
public function setTitle($title) {
$this->appendChild(new DOMElement('title', $title));
}
/**
* The URL of the item.
*
* @param String $link
*/
public function setLink($link) {
if(!filter_var($link, FILTER_VALIDATE_URL)) {
throw new RssFeedException($link.' is not a valid url.');
}
$this->appendChild(new DOMElement('link', $link));
}
/**
* The item synopsis.
*
* @param String/DOMCDATASection $description
*/
public function setDescription($description) {
if($description instanceof DOMCDATASection) {
$descriptionEl = $this->appendChild(new DOMElement('description'));
$descriptionEl->appendChild($description);
} else {
$this->appendChild(new DOMElement('description', $description));
}
}
/**
* Email address of the author of the item.
*
* @param String $author
*/
public function setAuthor($author) {
$this->appendChild(new DOMElement('author', $author));
}
/**
* Indicates when the item was published.
*
* @param DateTime $pubDate
*/
public function setPubDate(DateTime $pubDate) {
$this->appendChild(new DOMElement('pubDate', $pubDate->format(DATE_RSS)));
}
/**
* Includes the item in one or more categories.
*
* @param String $category
* @param String $domain
*/
public function setCategory($category, $domain=null) {
$category = $this->appendChild(new DOMElement('category', $category));
if(!is_null($domain)) {
$category->setAttribute('domain', $domain);
}
}
/**
* URL of a page for comments relating to the item.
*
* @param String $comments
*/
public function setComments($comments) {
if(!filter_var($comments, FILTER_VALIDATE_URL)) {
throw new RssFeedException($comments.' is not a valid url.');
}
$this->appendChild(new DOMElement('comments', $comments));
}
/**
* Describes a media object that is attached to the item.
*
* @param String $url
* @param Integer $length
* @param String $type
*/
public function setEnclosure($url, $length, $type) {
if(!is_integer($length)) {
throw new RssFeedException('length should be an integer representing the bit size of the enclosure.');
}
$enclosure = $this->appendChild(new DOMElement('enclosure'));
$enclosure->setAttribute('url', $url);
$enclosure->setAttribute('length', $length);
$enclosure->setAttribute('type', $type);
}
/**
* A string that uniquely identifies the item.
*
* @param String $guid
* @param Boolean $isPermaLink
*/
public function setGuid($guid, $isPermaLink=false) {
if($isPermaLink && !filter_var($guid, FILTER_VALIDATE_URL)) {
throw new RssFeedException('If isPermaLink is set true, guid should be an url.');
}
$guid = $this->appendChild(new DOMElement('guid', $guid));
if($isPermaLink) {
$guid->setAttribute('isPermaLink', 'true');
}
}
/**
* The RSS channel that the item came from.
*
* @param String $source
* @param String $url
*/
public function setSource($source, $url) {
if(!filter_var($url, FILTER_VALIDATE_URL)) {
throw new RssFeedException($url.' is not a valid url.');
}
$source = $this->appendChild(new DOMElement('source', $source));
$source->setAttribute('url', $url);
}
}
/**
* Special exception class for RssFeed* classes
*
* @author Boaz den Besten
* @copyright GNU/GPL
* @version @version@
*/
class RssFeedException extends Exception {
}
?>
Reacties
0