Begin rss changes feed
Begin rss changes feed


Former-commit-id: 2db905c6c7ff18136ba11420eb7ecb4c9fe743c1

--- a/getAgency.php
+++ b/getAgency.php
@@ -62,7 +62,9 @@
         //print_r($_POST);
         if (isset($_POST['_id']) && $db->get_rev($_POST['_id']) == $_POST['_rev']) {
             echo "Edited version was latest version, continue saving";
-            $row = $db->save($_POST);
+            $newdoc = $_POST;
+            $newdoc['metadata']['lastModified'] = time();
+            $row = $db->save($newdoc);
         } else {
             echo "ALERT doc revised by someone else while editing.";
         }

--- a/include/couchdb.inc.php
+++ b/include/couchdb.inc.php
@@ -1,5 +1,7 @@
 <?php
+
 include "schemas/schemas.inc.php";
+
 function createAgencyDesignDoc() {
     global $db;
     $obj = new stdClass();
@@ -7,10 +9,12 @@
     $obj->language = "javascript";
     $obj->views->byABN->map = "function(doc) {   emit(doc.abn, doc); };";
     $obj->views->byName->map = "function(doc) {   emit(doc.name, doc); };";
+    $obj->views->byLastModified->map = "function(doc) {   emit(doc.metadata.lastModified, doc); }";
     $obj->views->getActive->map = 'function(doc) { if (doc.status == "active") {  emit(doc._id, doc); } };';
     $obj->views->getSuspended->map = 'function(doc) { if (doc.status == "suspended") {  emit(doc._id, doc); } };';
     $obj->views->getScrapeRequired->map = "function(doc) {   emit(doc.abn, doc); };";
     $obj->views->showNamesABNs->map = "function(doc) {   emit(doc._id, {name: doc.name, abn: doc.abn}); };";
+
     // allow safe updates (even if slightly slower due to extra: rev-detection check).
     return $db->save($obj, true);
 }

file:b/lib/FeedItem.php (new)
--- /dev/null
+++ b/lib/FeedItem.php
@@ -1,1 +1,168 @@
+<?php

+ /**

+ * Univarsel Feed Writer

+ * 

+ * FeedItem class - Used as feed element in FeedWriter class

+ *

+ * @package         UnivarselFeedWriter

+ * @author          Anis uddin Ahmad <anisniit@gmail.com>

+ * @link            http://www.ajaxray.com/projects/rss

+ */

+ class FeedItem

+ {

+	private $elements = array();    //Collection of feed elements

+	private $version;

+	

+	/**

+	* Constructor 

+	* 

+	* @param    contant     (RSS1/RSS2/ATOM) RSS2 is default. 

+	*/ 

+	function __construct($version = RSS2)

+	{    

+		$this->version = $version;

+	}

+	

+	/**

+	* Add an element to elements array

+	* 

+	* @access   public

+	* @param    srting  The tag name of an element

+	* @param    srting  The content of tag

+	* @param    array   Attributes(if any) in 'attrName' => 'attrValue' format

+	* @return   void

+	*/

+	public function addElement($elementName, $content, $attributes = null)

+	{

+		$this->elements[$elementName]['name']       = $elementName;

+		$this->elements[$elementName]['content']    = $content;

+		$this->elements[$elementName]['attributes'] = $attributes;

+	}

+	

+	/**

+	* Set multiple feed elements from an array. 

+	* Elements which have attributes cannot be added by this method

+	* 

+	* @access   public

+	* @param    array   array of elements in 'tagName' => 'tagContent' format.

+	* @return   void

+	*/

+	public function addElementArray($elementArray)

+	{

+		if(! is_array($elementArray)) return;

+		foreach ($elementArray as $elementName => $content) 

+		{

+			$this->addElement($elementName, $content);

+		}

+	}

+	

+	/**

+	* Return the collection of elements in this feed item

+	* 

+	* @access   public

+	* @return   array

+	*/

+	public function getElements()

+	{

+		return $this->elements;

+	}

+	

+	// Wrapper functions ------------------------------------------------------

+	

+	/**

+	* Set the 'dscription' element of feed item

+	* 

+	* @access   public

+	* @param    string  The content of 'description' element

+	* @return   void

+	*/

+	public function setDescription($description) 

+	{

+		$tag = ($this->version == ATOM)? 'summary' : 'description'; 

+		$this->addElement($tag, $description);

+	}

+	

+	/**

+	* @desc     Set the 'title' element of feed item

+	* @access   public

+	* @param    string  The content of 'title' element

+	* @return   void

+	*/

+	public function setTitle($title) 

+	{

+		$this->addElement('title', $title);  	

+	}

+	

+	/**

+	* Set the 'date' element of feed item

+	* 

+	* @access   public

+	* @param    string  The content of 'date' element

+	* @return   void

+	*/

+	public function setDate($date) 

+	{

+		if(! is_numeric($date))

+		{

+			$date = strtotime($date);

+		}

+		

+		if($this->version == ATOM)

+		{

+			$tag    = 'updated';

+			$value  = date(DATE_ATOM, $date);

+		}        

+		elseif($this->version == RSS2) 

+		{

+			$tag    = 'pubDate';

+			$value  = date(DATE_RSS, $date);

+		}

+		else                                

+		{

+			$tag    = 'dc:date';

+			$value  = date("Y-m-d", $date);

+		}

+		

+		$this->addElement($tag, $value);    

+	}

+	

+	/**

+	* Set the 'link' element of feed item

+	* 

+	* @access   public

+	* @param    string  The content of 'link' element

+	* @return   void

+	*/

+	public function setLink($link) 

+	{

+		if($this->version == RSS2 || $this->version == RSS1)

+		{

+			$this->addElement('link', $link);

+		}

+		else

+		{

+			$this->addElement('link','',array('href'=>$link));

+			$this->addElement('id', FeedWriter::uuid($link,'urn:uuid:'));

+		} 

+		

+	}

+	

+	/**

+	* Set the 'encloser' element of feed item

+	* For RSS 2.0 only

+	* 

+	* @access   public

+	* @param    string  The url attribute of encloser tag

+	* @param    string  The length attribute of encloser tag

+	* @param    string  The type attribute of encloser tag

+	* @return   void

+	*/

+	public function setEncloser($url, $length, $type)

+	{

+		$attributes = array('url'=>$url, 'length'=>$length, 'type'=>$type);

+		$this->addElement('enclosure','',$attributes);

+	}

+	

+ } // end of class FeedItem

+?>

 

--- /dev/null
+++ b/lib/FeedWriter.php
@@ -1,1 +1,435 @@
-
+<?php

+// RSS 0.90  Officially obsoleted by 1.0

+// RSS 0.91, 0.92, 0.93 and 0.94  Officially obsoleted by 2.0

+// So, define constants for RSS 1.0, RSS 2.0 and ATOM 	

+

+	define('RSS1', 'RSS 1.0', true);

+	define('RSS2', 'RSS 2.0', true);

+	define('ATOM', 'ATOM', true);

+

+ /**

+ * Univarsel Feed Writer class

+ *

+ * Genarate RSS 1.0, RSS2.0 and ATOM Feed

+ *                             

+ * @package     UnivarselFeedWriter

+ * @author      Anis uddin Ahmad <anisniit@gmail.com>

+ * @link        http://www.ajaxray.com/projects/rss

+ */

+ class FeedWriter

+ {

+	 private $channels      = array();  // Collection of channel elements

+	 private $items         = array();  // Collection of items as object of FeedItem class.

+	 private $data          = array();  // Store some other version wise data

+	 private $CDATAEncoding = array();  // The tag names which have to encoded as CDATA

+	 

+	 private $version   = null; 

+	

+	/**

+	* Constructor

+	* 

+	* @param    constant    the version constant (RSS1/RSS2/ATOM).       

+	*/ 

+	function __construct($version = RSS2)

+	{	

+		$this->version = $version;

+			

+		// Setting default value for assential channel elements

+		$this->channels['title']        = $version . ' Feed';

+		$this->channels['link']         = 'http://www.ajaxray.com/blog';

+				

+		//Tag names to encode in CDATA

+		$this->CDATAEncoding = array('description', 'content:encoded', 'summary');

+	}

+

+	// Start # public functions ---------------------------------------------

+	

+	/**

+	* Set a channel element

+	* @access   public

+	* @param    srting  name of the channel tag

+	* @param    string  content of the channel tag

+	* @return   void

+	*/

+	public function setChannelElement($elementName, $content)

+	{

+		$this->channels[$elementName] = $content ;

+	}

+	

+	/**

+	* Set multiple channel elements from an array. Array elements 

+	* should be 'channelName' => 'channelContent' format.

+	* 

+	* @access   public

+	* @param    array   array of channels

+	* @return   void

+	*/

+	public function setChannelElementsFromArray($elementArray)

+	{

+		if(! is_array($elementArray)) return;

+		foreach ($elementArray as $elementName => $content) 

+		{

+			$this->setChannelElement($elementName, $content);

+		}

+	}

+	

+	/**

+	* Genarate the actual RSS/ATOM file

+	* 

+	* @access   public

+	* @return   void

+	*/ 

+	public function genarateFeed()

+	{

+		header("Content-type: text/xml");

+		

+		$this->printHead();

+		$this->printChannels();

+		$this->printItems();

+		$this->printTale();

+	}

+	

+	/**

+	* Create a new FeedItem.

+	* 

+	* @access   public

+	* @return   object  instance of FeedItem class

+	*/

+	public function createNewItem()

+	{

+		$Item = new FeedItem($this->version);

+		return $Item;

+	}

+	

+	/**

+	* Add a FeedItem to the main class

+	* 

+	* @access   public

+	* @param    object  instance of FeedItem class

+	* @return   void

+	*/

+	public function addItem($feedItem)

+	{

+		$this->items[] = $feedItem;    

+	}

+	

+	

+	// Wrapper functions -------------------------------------------------------------------

+	

+	/**

+	* Set the 'title' channel element

+	* 

+	* @access   public

+	* @param    srting  value of 'title' channel tag

+	* @return   void

+	*/

+	public function setTitle($title)

+	{

+		$this->setChannelElement('title', $title);

+	}

+	

+	/**

+	* Set the 'description' channel element

+	* 

+	* @access   public

+	* @param    srting  value of 'description' channel tag

+	* @return   void

+	*/

+	public function setDescription($desciption)

+	{

+		$this->setChannelElement('description', $desciption);

+	}

+	

+	/**

+	* Set the 'link' channel element

+	* 

+	* @access   public

+	* @param    srting  value of 'link' channel tag

+	* @return   void

+	*/

+	public function setLink($link)

+	{

+		$this->setChannelElement('link', $link);

+	}

+	

+	/**

+	* Set the 'image' channel element

+	* 

+	* @access   public

+	* @param    srting  title of image

+	* @param    srting  link url of the imahe

+	* @param    srting  path url of the image

+	* @return   void

+	*/

+	public function setImage($title, $link, $url)

+	{

+		$this->setChannelElement('image', array('title'=>$title, 'link'=>$link, 'url'=>$url));

+	}

+	

+	/**

+	* Set the 'about' channel element. Only for RSS 1.0

+	* 

+	* @access   public

+	* @param    srting  value of 'about' channel tag

+	* @return   void

+	*/

+	public function setChannelAbout($url)

+	{

+		$this->data['ChannelAbout'] = $url;    

+	}

+	

+  /**

+  * Genarates an UUID

+  * @author     Anis uddin Ahmad <admin@ajaxray.com>

+  * @param      string  an optional prefix

+  * @return     string  the formated uuid

+  */

+  public function uuid($key = null, $prefix = '') 

+  {

+	$key = ($key == null)? uniqid(rand()) : $key;

+	$chars = md5($key);

+	$uuid  = substr($chars,0,8) . '-';

+	$uuid .= substr($chars,8,4) . '-';

+	$uuid .= substr($chars,12,4) . '-';

+	$uuid .= substr($chars,16,4) . '-';

+	$uuid .= substr($chars,20,12);

+

+	return $prefix . $uuid;

+  }

+	// End # public functions ----------------------------------------------

+	

+	// Start # private functions ----------------------------------------------

+	

+	/**

+	* Prints the xml and rss namespace

+	* 

+	* @access   private

+	* @return   void

+	*/

+	private function printHead()

+	{

+		$out  = '<?xml version="1.0" encoding="utf-8"?>' . "\n";

+		

+		if($this->version == RSS2)

+		{

+			$out .= '<rss version="2.0"

+					xmlns:content="http://purl.org/rss/1.0/modules/content/"

+					xmlns:wfw="http://wellformedweb.org/CommentAPI/"

+				  >' . PHP_EOL;

+		}    

+		elseif($this->version == RSS1)

+		{

+			$out .= '<rdf:RDF 

+					 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

+					 xmlns="http://purl.org/rss/1.0/"

+					 xmlns:dc="http://purl.org/dc/elements/1.1/"

+					>' . PHP_EOL;;

+		}

+		else if($this->version == ATOM)

+		{

+			$out .= '<feed xmlns="http://www.w3.org/2005/Atom">' . PHP_EOL;;

+		}

+		echo $out;

+	}

+	

+	/**

+	* Closes the open tags at the end of file

+	* 

+	* @access   private

+	* @return   void

+	*/

+	private function printTale()

+	{

+		if($this->version == RSS2)

+		{

+			echo '</channel>' . PHP_EOL . '</rss>'; 

+		}    

+		elseif($this->version == RSS1)

+		{

+			echo '</rdf:RDF>';

+		}

+		else if($this->version == ATOM)

+		{

+			echo '</feed>';

+		}

+	  

+	}

+

+	/**

+	* Creates a single node as xml format

+	* 

+	* @access   private

+	* @param    srting  name of the tag

+	* @param    mixed   tag value as string or array of nested tags in 'tagName' => 'tagValue' format

+	* @param    array   Attributes(if any) in 'attrName' => 'attrValue' format

+	* @return   string  formatted xml tag

+	*/

+	private function makeNode($tagName, $tagContent, $attributes = null)

+	{        

+		$nodeText = '';

+		$attrText = '';

+

+		if(is_array($attributes))

+		{

+			foreach ($attributes as $key => $value) 

+			{

+				$attrText .= " $key=\"$value\" ";

+			}

+		}

+		

+		if(is_array($tagContent) && $this->version == RSS1)

+		{

+			$attrText = ' rdf:parseType="Resource"';

+		}

+		

+		

+		$attrText .= (in_array($tagName, $this->CDATAEncoding) && $this->version == ATOM)? ' type="html" ' : '';

+		$nodeText .= (in_array($tagName, $this->CDATAEncoding))? "<{$tagName}{$attrText}><![CDATA[" : "<{$tagName}{$attrText}>";

+		 

+		if(is_array($tagContent))

+		{ 

+			foreach ($tagContent as $key => $value) 

+			{

+				$nodeText .= $this->makeNode($key, $value);

+			}

+		}

+		else

+		{

+			$nodeText .= (in_array($tagName, $this->CDATAEncoding))? $tagContent : htmlentities($tagContent);

+		}           

+			

+		$nodeText .= (in_array($tagName, $this->CDATAEncoding))? "]]></$tagName>" : "</$tagName>";

+

+		return $nodeText . PHP_EOL;

+	}

+	

+	/**

+	* @desc     Print channels

+	* @access   private

+	* @return   void

+	*/

+	private function printChannels()

+	{

+		//Start channel tag

+		switch ($this->version) 

+		{

+		   case RSS2: 

+				echo '<channel>' . PHP_EOL;        

+				break;

+		   case RSS1: 

+				echo (isset($this->data['ChannelAbout']))? "<channel rdf:about=\"{$this->data['ChannelAbout']}\">" : "<channel rdf:about=\"{$this->channels['link']}\">";

+				break;

+		}

+		

+		//Print Items of channel

+		foreach ($this->channels as $key => $value) 

+		{

+			if($this->version == ATOM && $key == 'link') 

+			{

+				// ATOM prints link element as href attribute

+				echo $this->makeNode($key,'',array('href'=>$value));

+				//Add the id for ATOM

+				echo $this->makeNode('id',$this->uuid($value,'urn:uuid:'));

+			}

+			else

+			{

+				echo $this->makeNode($key, $value);

+			}    

+			

+		}

+		

+		//RSS 1.0 have special tag <rdf:Seq> with channel 

+		if($this->version == RSS1)

+		{

+			echo "<items>" . PHP_EOL . "<rdf:Seq>" . PHP_EOL;

+			foreach ($this->items as $item) 

+			{

+				$thisItems = $item->getElements();

+				echo "<rdf:li resource=\"{$thisItems['link']['content']}\"/>" . PHP_EOL;

+			}

+			echo "</rdf:Seq>" . PHP_EOL . "</items>" . PHP_EOL . "</channel>" . PHP_EOL;

+		}

+	}

+	

+	/**

+	* Prints formatted feed items

+	* 

+	* @access   private

+	* @return   void

+	*/

+	private function printItems()

+	{    

+		foreach ($this->items as $item) 

+		{

+			$thisItems = $item->getElements();

+			

+			//the argument is printed as rdf:about attribute of item in rss 1.0 

+			echo $this->startItem($thisItems['link']['content']);

+			

+			foreach ($thisItems as $feedItem ) 

+			{

+				echo $this->makeNode($feedItem['name'], $feedItem['content'], $feedItem['attributes']); 

+			}

+			echo $this->endItem();

+		}

+	}

+	

+	/**

+	* Make the starting tag of channels

+	* 

+	* @access   private

+	* @param    srting  The vale of about tag which is used for only RSS 1.0

+	* @return   void

+	*/

+	private function startItem($about = false)

+	{

+		if($this->version == RSS2)

+		{

+			echo '<item>' . PHP_EOL; 

+		}    

+		elseif($this->version == RSS1)

+		{

+			if($about)

+			{

+				echo "<item rdf:about=\"$about\">" . PHP_EOL;

+			}

+			else

+			{

+				die('link element is not set .\n It\'s required for RSS 1.0 to be used as about attribute of item');

+			}

+		}

+		else if($this->version == ATOM)

+		{

+			echo "<entry>" . PHP_EOL;

+		}    

+	}

+	

+	/**

+	* Closes feed item tag

+	* 

+	* @access   private

+	* @return   void

+	*/

+	private function endItem()

+	{

+		if($this->version == RSS2 || $this->version == RSS1)

+		{

+			echo '</item>' . PHP_EOL; 

+		}    

+		else if($this->version == ATOM)

+		{

+			echo "</entry>" . PHP_EOL;

+		}

+	}

+	

+

+	

+	// End # private functions ----------------------------------------------

+	

+ } // end of class FeedWriter

+ 

+// autoload classes

+function __autoload($class_name) 

+{

+	require_once $class_name . '.php';

+}

file:b/rss.xml.php (new)
--- /dev/null
+++ b/rss.xml.php
@@ -1,1 +1,30 @@
+<?php
 
+// Agency X updated Y,  new files, diff of plain text/link text,
+// feed for just one agency or all
+// This is a minimum example of using the Universal Feed Generator Class
+include("lib/FeedWriter.php");
+//Creating an instance of FeedWriter class.
+$TestFeed = new FeedWriter(RSS2);
+//Setting the channel elements
+//Use wrapper functions for common channelelements
+$TestFeed->setTitle('Last Modified - All');
+$TestFeed->setLink('http://disclosr.lambdacomplex.org/rss.xml.php');
+$TestFeed->setDescription('This is test of creating a RSS 2.0 feed Universal Feed Writer');
+//Retriving informations from database
+$rows = $db->get_view("app", "byLastModified")->rows;
+//print_r($rows);
+foreach ($rows as $row) {
+    //Create an empty FeedItem
+    $newItem = $TestFeed->createNewItem();
+    //Add elements to the feed item
+    $newItem->setTitle($row['name']);
+    $newItem->setLink($row['id']);
+    $newItem->setDate(date("c", $row['metadata']['lastModified']));
+    $newItem->setDescription($row['name']);
+    //Now add the feed item
+    $TestFeed->addItem($newItem);
+}
+//OK. Everything is done. Now genarate the feed.
+$TestFeed->genarateFeed();
+?>

--- a/unimplemented/rss.xml.php
+++ /dev/null
@@ -1,2 +1,1 @@
-// Agency X updated Y,  new files, diff of plain text/link text,
-// feed for just one agency or all
+