This topic is locked

How to subscribe to database changes via RSS

12/1/2010 10:49:40 PM
PHPRunner Tips and Tricks
Sergey Kornilov admin

RSS is a format for delivering regularly changing web content. Many news-related sites, weblogs and other online publishers syndicate their content as an RSS Feed to whoever wants it.
For example, this forum allows you to subscribe to new topics via RSS. In this article we'll show you now you can add similar functionality to your PHPRunner project. If you are interested in learning RSS specification read this document.
This is the first article of two-part series explores the basic RSS subscription to database changes. Second article covers signing for data updates matching specific SQL queries.
[size="5"]1. Create file named rss.php[/size]

and save it to output directory (where all generated files reside)
Copy and paste the following code there.

<?php
include("include/dbcommon.php");



// timestamp field, leave empty if not applicable

$datefield=$_REQUEST["datefield"];
// table name

if (!$_REQUEST["table"])

exit();
include("include/".$_REQUEST["table"]."_variables.php");
$tablename=GetTableByShort($_REQUEST["table"]);
// get key columns

$keycolumns = GetTableData($tablename,".arrKeyFields",array());
$entries = 15; // how many items to display
class RSSFeed {

// VARIABLES

// channel vars

var $channel_title;

var $channel_url;

var $channel_description;

var $channel_lang;

var $channel_copyright;

var $channel_date;

var $image_url;

var $items = array();

var $nritems;



// FUNCTIONS

// constructor

function RSSFeed() {

$this->nritems=0;

$this->channel_url='';

$this->channel_title='';

$this->channel_description='';

$this->channel_lang='';

$this->channel_copyright='';

$this->channel_date='';

$this->image_url='';

}

// set channel vars

function SetChannel($url, $title, $description, $lang, $copyright) {

$this->channel_url=$url;

$this->channel_title=$title;

$this->channel_description=$description;

$this->channel_lang=$lang;

$this->channel_copyright=$copyright;

$this->channel_date=date("D, j M Y H:i:s O");

}

// set image

function SetImage($url) {

$this->image_url=$url;

}

// set item

function SetItem($url, $title, $description, $pubdate) {

$this->items[$this->nritems]['url']=$url;

$this->items[$this->nritems]['title']=$title;

$this->items[$this->nritems]['description']=$description;

$this->items[$this->nritems]['pubdate']=$pubdate;

$this->nritems++;

}

// output feed

function Output() {

$output = '<?xml version="1.0" encoding="UTF-8"?>'."\n";

$output .= '<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/">';

$output .= '<channel>'."\n";

$output .= '<title>'.xmlencode($this->channel_title).'</title>'."\n";

$output .= '<link>'.xmlencode($this->channel_url).'</link>'."\n";

$output .= '<description>'.xmlencode($this->channel_description).'</description>'."\n";

$output .= '<copyright>'.$this->channel_copyright.'</copyright>'."\n";

$output .= '<language>'.$this->channel_lang.'</language>'."\n";

$output .= '<pubDate>'.$this->channel_date.'</pubDate>'."\n";

$output .= '<ttl>60</ttl>'."\n";

for($k=0; $k<$this->nritems; $k++) {

$output .= '<item>'."\n";

$output .= '<title>'.xmlencode($this->items[$k]['title']).'</title>'."\n";

$output .= '<link>'.xmlencode($this->items[$k]['url']).'</link>'."\n";

$output .= '<description>'.xmlencode($this->items[$k]['description']).'</description>'."\n";

$output .= '<pubDate>'.$this->items[$k]['pubdate'].'</pubDate>'."\n";

$output .= '<guid isPermaLink="true">'.$this->items[$k]['url'].'</guid>'."\n";

$output .= '</item>'."\n";

};

$output .= '</channel>'."\n";

$output .= '</rss>'."\n";

return $output;

}

function xmlencode($str)

{
$str = str_replace("&","&",$str);

$str = str_replace("<","<",$str);

$str = str_replace(">",">",$str);

$str = str_replace("'","'",$str);

$str = str_replace("’","'",$str);

$str = str_replace("“","'",$str);

$str = str_replace("”","'",$str);

return $str;

}



function getURLPath() {

$pageURL = 'http';

if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}

$pageURL .= "://";

if ($_SERVER["SERVER_PORT"] != "80") {

$pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];

} else {

$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];

}



$pageURL = substr($pageURL, 0, strrpos($pageURL, "/")+1 );

return $pageURL;

}



};
// set feed parameters

$myfeed = new RSSFeed();

$myfeed->SetChannel('http://www.yourwebsite.com/',

'Yourwebsite.com, Table '.$tablename.' RSS Feed',

'feed description',

'en-us',

'Copyright (c) 2010 www.yourwebsite.com');

// $myfeed->SetImage('https://asprunner.com/forums/file.php?topicimage=1&fieldname=question&id=15866&image=1&table=forumtopics');





$sql = "select * from $tablename";



// add order by datefield or by key column descended

if ($datefield)

$sql.= " order by ".AddFieldWrappers($datefield)." desc";

else if (count($keycolumns)>0)

{

$sql .= " order by ";

foreach($keycolumns as $key)

{

$sql.=AddFieldWrappers($key)." desc," ;

}

$sql = substr($sql, 0, strlen($sql)-1);

}
// limit number of records
if ($globalSettings["dbType"]==0 || $globalSettings["dbType"]==4) // MySQL or Postgre

$sql .= " limit ".$entries;

else if ($globalSettings["dbType"]==1) // Oracle

$sql = AddRowNumber($sql, $entries);

else if ($globalSettings["dbType"]==2 || $globalSettings["dbType"]==3) // SQL Server

$sql = AddTop($sql, $entries);


//fetch tha data from the database



$rs = CustomQuery($sql);
while ($data = db_fetch_array($rs))

{

// link

$link=$tablename."_view.php?";

$title="";

$n=1;

foreach($keycolumns as $key)

{

$link.="editid".$n."=".$data[$key]."&";

$title.=$key.": ".$data[$key].", ";

$n++;

}

$link = $myfeed->getURLPath().substr($link, 0, strlen($link)-1);

$title = substr($title, 0, strlen($title)-2);



$description="";

// description

foreach($data as $field => $value)

{

if(IsBinaryType(GetFieldType($field,$tablename)))

continue;

$description.=$field.": ".$value."\n";

}



// pubDate

if ($datefield)

$date = date('D, j M Y H:i:s O', strtotime($data[$datefield]));

else

$date="";



$myfeed->SetItem($link,$title,$description,$date);

}





header('Content-Type: text/xml');

echo $myfeed->output();

?>


You may want to customize the following
Number of records RSS feed needs to include:

$entries = 15;


RSS channel meta data

$myfeed->SetChannel('http://www.yourwebsite.com/',

'Yourwebsite.com, Table '.$tablename.' RSS Feed',

'feed description',

'en-us',

'Copyright (c) 2010 www.yourwebsite.com');

// $myfeed->SetImage('https://asprunner.com/forums/file.php?topicimage=1&fieldname=question&id=15866&image=2&table=forumtopics');


By default RSS channel description adds your website name and table name.
[size="5"]2. Pick your favorite RSS icon[/size]

and save it as images/rss.png
[size="5"]3. Add RSS icon to the list page[/size]

In PHPRunner proceed to Visual Editor, open List page of any table and insert PHP code snippet where you want to display RSS feed icon

global $strTableName;

echo "<a href='rss.php?table=".$strTableName."&datefield=Created'><img src=images/rss.png border=0></a>";


In this example Created is a field that stores record creation timestamp. This parameter serves two purposes:

  1. Allows to add pubDate parameter to RSS item
  2. Allows to sort data the proper way so new items appear on the top
    This parameter is optional. If your database table doesn't have timestamp field you can use the following code snippet:

global $strTableName;

echo "<a href='rss.php?table=".$strTableName."'><img src=images/rss.png border=0></a>";


In this case rss.php file will sort data by key columns in descending order.
Add similar code snippet to each table you want to publish via RSS.
Here is the live example:

http://demo.asprunner.net/volinrok_yahoo_com/RSS/Cars_list.php
RSS icon is in the top right corner. Subscribe via you favorite RSS Reader (Google Reader is recommended) then add a new record or two to this table to see new data coming via RSS.