<?php
/*
The DynamicRSS PHP Class
By Cory S.N. LaViska
Version 1.0, December 07, 2008
Easily create a dynamic RSS 2.0 feed from items in your MySQL database.
LICENSE & COPYRIGHT
Copyright (C) 2008 A Beautiful Site, LLC. (http://abeautifulsite.net)
For full documentation, visit http://abeautifulsite.net/notebook/86
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
RSS 2.0 Documentation
http://cyber.law.harvard.edu/rss/rss.html
SAMPLE USAGE
$rss = new DynamicRSS();
$rss->db('localhost', 'db_name', 'db_user', 'db_password')
->query('[your_mysql_query_to_fetch_items]')
->channel( array(
'title'=>'Example RSS Feed',
'link'=>'http://example.com/',
'description'=>'Feed Description',
'language'=>'en-us',
'copyright'=>'Copyright 2008 Nobody, Inc.',
'managingEditor'=>'hide@address.com (FirstName LastName)'
))
->item( array(
'title'=>'[your_mysql_title_field]',
'link'=>'[your_mysql_link_field]',
'author'=>'[your_mysql_author_field]',
'description'=>'[your_mysql_description_field]',
'guid'=>'[your_mysql_guid_field]', // usually the same as 'link'
'pubDate'=>'[your_mysql_pubDate_field]'
))
->generate();
* Reference database fields in query() and item_xml() methods using {{field_name}}
*/
class DynamicRSS {
// Required
public $db = array(), $feed_url, $indent, $channel, $channel_xml, $item, $item_xml;
private $feed_data;
function __construct() {
// Default values
$this->item = array();
$this->channel = array();
$this->indent = ' ';
// Determine self URL (manually override with the feed_url method)
$url = parse_url(preg_match('/^https/i', $_SERVER['SCRIPT_URI']) ? 'https' : 'http' . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]");
$url = "$url[scheme]://$url[host]$url[path]";
if( strlen($url['query']) > 1 ) $url .= "?{$url[query]}";
$this->feed_url = $url;
}
public function db($host, $name, $user, $pass, $type='mysql') {
$this->db['host'] = $host;
$this->db['name'] = $name;
$this->db['user'] = $user;
$this->db['pass'] = $pass;
$this->db['type'] = $type;
return $this;
}
public function query($query) {
$this->db['query'] = $query;
return $this;
}
public function feed_url($feed_url) {
$this->feed_url = $feed_url;
return $this;
}
public function indent($indent) {
$this->indent = (string)$indent;
return $this;
}
public function channel($channel = array()) {
foreach( $channel as $key=>$value ) $this->channel[$key] = $value;
return $this;
}
public function channel_xml($channel_xml) {
$this->channel_xml = $channel_xml;
return $this;
}
public function image($url, $width = null, $height = null) {
// Adjust width/height to default if they exceed the maximum
$width = $width > 144 ? 88 : intval($width);
$height = $height > 400 ? 31 : intval($height);
$this->channel['image']['url'] = $url;
$this->channel['image']['title'] = $this->channel['title'];
$this->channel['image']['link'] = $this->channel['link'];
$this->channel['image']['width'] = $width;
$this->channel['image']['height'] = $height;
return $this;
}
public function item( $item = array() ) {
foreach( $item as $key=>$value ) $this->item[$key] = $value;
return $this;
}
public function item_xml($item_xml) {
$this->item_xml = $item_xml;
return $this;
}
public function generate($output = 'screen') {
$this->generate_rss();
switch( $output ) {
case 'string':
return $this->feed_data;
break;
case 'screen':
header("Content-Type: application/rss+xml");
echo $this->feed_data;
return $this;
break;
default:
exit('Invalid output mode');
break;
}
}
private function xmlentities($string) {
// Developer note: need to have a XML compliant to replace this
return htmlentities($string);
}
private function generate_rss() {
// Open feed
$this->feed_data = "<?xml version = \"1.0\"?>\n";
$this->feed_data .= "<rss version=\"2.0\" xmlns:atom=\"http://www.w3.org/2005/Atom\">\n";
$this->feed_data .= "$this->indent<channel>\n";
$this->feed_data .= "$this->indent$this->indent<atom:link href=\"" . $this->feed_url . "\" rel=\"self\" type=\"application/rss+xml\" />\n";
// Channel Elements
foreach( $this->channel as $key=>$value ) {
if( !is_array($this->channel[$key]) ) {
// Element
$this->feed_data .= "$this->indent$this->indent<$key>" . $this->xmlentities($value) . "</$key>\n";
} else {
// Sub-element
$this->feed_data .= "$this->indent$this->indent<$key>\n";
foreach( $this->channel[$key] as $subkey=>$subvalue ) $this->feed_data .= "$this->indent$this->indent$this->indent<$subkey>" . $this->xmlentities($subvalue) . "</$subkey>\n";
$this->feed_data .= "$this->indent$this->indent</$key>\n";
}
}
// Raw channel XML
if( !empty($this->channel_xml) ) $this->feed_data .= "$this->indent$this->indent$this->channel_xml";
// Item
$d = @mysql_connect($this->db['host'], $this->db['user'], $this->db['pass']);
if( !$d ) exit('Unable to establish a MySQL connection');
if( !@mysql_select_db($this->db['name'], $d) ) exit('Unable to connect to database');
$item = mysql_query($this->db['query']);
if( !$item ) exit('Failed to execute query');
while( $row = mysql_fetch_array($item) ) {
$this->feed_data .= "$this->indent$this->indent<item>\n";
foreach( $this->item as $key=>$value ) {
// Replace {field_name} with the value from the corresponding database field
preg_match_all('/\{([A-Za-z0-9-_]+)\}/', $row[$key], $m);
for( $i = 0; $i < count($m); $i++ ) $row[$key] = preg_replace('/\{\{([A-Za-z0-9-_]+)\}\}/', $row[$m[1][$i]], $row[$key]);
// Add the element
$this->feed_data .= "$this->indent$this->indent$this->indent<$key>" . $this->xmlentities($row[$value]) . "</$key>\n";
}
// Sub-elements
if( !empty($this->item_xml) ) {
// Replace {field_name} with the value from the corresponding database field
preg_match_all('/\{([A-Za-z0-9-_]+)\}/', $this->item_xml, $m);
for( $i = 0; $i < count($m); $i++ ) $this->item_xml = preg_replace('/\{\{([A-Za-z0-9-_]+)\}\}/', $row[$m[1][$i]], $this->item_xml);
$this->feed_data .= "$this->indent$this->indent$this->indent$this->item_xml\n";
}
$this->feed_data .= "$this->indent$this->indent</item>\n";
}
// Close feed
$this->feed_data .= "$this->indent</channel>\n";
$this->feed_data .= "</rss>";
return $this;
}
}
?>