Return to Snippet

Revision: 22585
at January 16, 2010 13:45 by iloveitaly


Initial Code
<?
class Feed2 extends feed {
	/**
	 * Creates a feed from the given parameters.
	 *
	 * @param   array   feed information
	 * @param   array   items to add to the feed
	 * @param   string  define which format to use
	 * @param   string  define which encoding to use
	 * @return  string
	 */
	public static function create($info, $items, $format = 'rss2', $encoding = 'UTF-8')
	{
		$info += array('title' => 'Generated Feed', 'link' => '', 'generator' => 'KohanaPHP');

		// handle namespaces
		$namespaceString = '';
		
		if(isset($info['namespaces'])) {
			foreach($info['namespaces'] as $prefix => $ns) {
				// can't add namespaces using the api bc it adds in xmlns:xmlns="..." which is explicitly declared as invalid xml: http://www.w3.org/TR/REC-xml-names/#xmlReserved
				// $feed->addAttribute('xmlns:'.$prefix, $ns, 'http://www.w3.org/2000/xmlns/');
				
				$namespaceString .= " xmlns:".$prefix.'="'.$ns.'"';
			}
			
			$namespaces = $info['namespaces'];
			
			// this is so it is not included in the rest of the $info generation
			unset($info['namespaces']);
		}
		
		$feed = '<?xml version="1.0" encoding="'.$encoding.'"?><rss version="2.0"'.$namespaceString.'><channel></channel></rss>';
		$feed = simplexml_load_string($feed);
		
		foreach ($info as $name => $value)
		{
			if (($name === 'pubDate' OR $name === 'lastBuildDate') AND (is_int($value) OR ctype_digit($value)))
			{
				// Convert timestamps to RFC 822 formatted dates
				$value = date(DATE_RFC822, $value);
			}
			elseif (($name === 'link' OR $name === 'docs') AND strpos($value, '://') === FALSE)
			{
				// Convert URIs to URLs
				$value = url::site($value, 'http');
			}

			// Add the info to the channel
			$feed->channel->addChild($name, $value);
		}

		foreach ($items as $item)
		{
			// Add the item to the channel
			$row = $feed->channel->addChild('item');

			foreach ($item as $name => $value)
			{
				if(!is_array($value)) {
					if ($name === 'pubDate' AND (is_int($value) OR ctype_digit($value)))
					{
						// Convert timestamps to RFC 822 formatted dates
						$value = date(DATE_RFC822, $value);
					}
					elseif (($name === 'link' OR $name === 'guid') AND strpos($value, '://') === FALSE)
					{
						// Convert URIs to URLs
						$value = url::site($value, 'http');
					}
					
					// Add the info to the row
					$row->addChild($name, $value);
				} else {
					$child = $row->addChild($name);
					
					// If the value is an array we are specifying attributes
					foreach($value as $attribute => $attributeValue) {
						if(strchr($attribute, ':') !== FALSE) {
							list($ns, $attribute2) = explode(':', $attribute);
						} else {
							$ns = "";
						}
						
						//!empty($ns) ? $namespaces[$ns] : NULL
						$child->addAttribute($attribute, $attributeValue, !empty($ns) ? $namespaces[$ns] : NULL);
					}
				}
			}
		}

		return $feed->asXML();
	}
}

// Example Feed Generation (For Sparkle Update System):

$feedItems = array();

foreach(ORM::factory('updates')->find_all() as $clientUpdate) {
	$feedItems[] = array(
		'title' => 'v'.$clientUpdate->version,
		'pubDate' => $clientUpdate->date,
		'enclosure' => array(
			'url' => 'http://domain.com/',
			'type' => 'application/octet-stream',
			'length' => filesize('/path/to/file.zip'),
			'sparkle:dsaSignature' => 'dsasig',
			'sparkle:version' => '200',
			'sparkle:shortVersionString' => '1.0',
			'sparkle:minimumSystemVersion' => '10.6'
		)
	);
}

$feedData = feed2::create(
	array(
		'title' => 'Update Feed',
		'author' => 'Michael Bianco',
		'pubDate' => date('r'),
		'link' => 'http://domain.com/',
		'language' => 'en',
		'namespaces' => array(
			'sparkle' => 'http://www.andymatuschak.org/xml-namespaces/sparkle',
			'dc' => 'http://purl.org/dc/elements/1.1/'
		)
	),
	$feedItems
);

?>

Initial URL


Initial Description


Initial Title
Kohana Feed With Attributes & Namespace Support

Initial Tags
xml

Initial Language
PHP