Recipe 12.14. Writing Atom Feeds


12.14.1. Problem

You want to generate Atom feeds from your data. This will allow you to syndicate your content.

12.14.2. Solution

Use this class:

class atom1 extends DOMDocument {     private $ns;     public function __construct($title, $href, $name, $id) {         parent::__construct();         $this->formatOutput = true;         $this->ns = 'http://www.w3.org/2005/Atom';         $root = $this->appendChild($this->createElementNS($this->ns, 'feed'));         $root->appendChild($this->createElementNS($this->ns, 'title', $title));         $link = $root->appendChild($this->createElementNS($this->ns, 'link'));         $link->setAttribute('href', $href);         $root->appendChild($this->createElementNS($this->ns, 'updated',             date('Y-m-d\\TH:i:sP')));         $author = $root->appendChild($this->createElementNS($this->ns, 'author'));         $author->appendChild($this->createElementNS($this->ns, 'name', $name));         $root->appendChild($this->createElementNS($this->ns, 'id', $id));     }     public function addEntry($title, $link, $summary) {         $entry = $this->createElementNS($this->ns, 'entry');         $entry->appendChild($this->createElementNS($this->ns, 'title', $title));         $entry->appendChild($this->createElementNS($this->ns, 'link', $link));         $id = uniqid('http://example.org/atom/entry/ids/');         $entry->appendChild($this->createElementNS($this->ns, 'id', $id));         $entry->appendChild($this->createElementNS($this->ns, 'updated',             date(DATE_ATOM)));         $entry->appendChild($this->createElementNS($this->ns, 'summary',     $summary));         $this->documentElement->appendChild($entry);     } } $atom = new atom1('Channel Title', 'http://www.example.org',                 'John Quincy Atom', 'http://example.org/atom/feed/ids/1'); $atom->addEntry('Item 1', 'http://www.example.org/item1',               'Item 1 Description', 'http://example.org/atom/entry/ids/1'); $atom->addEntry('Item 2', 'http://www.example.org/item2',               'Item 2 Description', 'http://example.org/atom/entry/ids/2'); print $atom->saveXML(); <?xml version="1.0"?> <feed xmlns="http://www.w3.org/2005/Atom">   <title>Channel Title</title>   <link href="http://www.example.org"/>   <updated>2006-10-23T22:33:59-07:00</updated>   <author>     <name>John Quincy Atom</name>   </author>   <id>http://example.org/atom/feed/ids/1</id>   <entry>     <title>Item 1</title>     <link>http://www.example.org/item1</link>     <id>http://example.org/atom/entry/ids/1</id>     <updated>2006-10-23T20:23:32-07:00</updated>     <summary>Item 1 Description</summary>   </entry>   <entry>     <title>Item 2</title>     <link>http://www.example.org/item2</link>     <id>http://example.org/atom/entry/ids/2</id>     <updated>2006-10-23T21:53:44-07:00</updated>     <summary>Item 2 Description</summary>   </entry> </feed>

12.14.3. Discussion

The atom1 class is structured similar to the rss2 class from Recipe 12.13. Read its Discussion for a more detailed explanation of the overall code structure and DOM extension behavior. This recipe covers the differences between RSS and Atom and how the class is updated to handle them.

The Atom Specification is more complex than RSS. It requires you to place elements inside a namespace and also forces the generation of unique identifiers for a feed and individual items, along with the last updated times for those entries.

Also, while its general structure is similar to RSS, it uses different terminology. The root element is now a feed and an item is now an entry. You don't need a feed description, but you do need an author. And inside the entries, the description is a summary.

Last, there is no concept of a channel. Both feed data and entries are located directly under the document element.

Here's the updated constructor:

     public function __construct($title, $href, $name, $id) {         parent::__construct();         $this->formatOutput = true;         $this->ns = 'http://www.w3.org/2005/Atom';         $root = $this->appendChild($this->createElementNS($this->ns, 'feed'));         $root->appendChild(             $this->createElementNS($this->ns, 'title', $title));         $link = $root->appendChild(             $this->createElementNS($this->ns, 'link'));         $link->setAttribute('href', $href);         $root->appendChild($this->createElementNS(             $this->ns, 'updated', date(DATE_ATOM)));         $author = $root->appendChild(             $this->createElementNS($this->ns, 'author'));         $author->appendChild(             $this->createElementNS($this->ns, 'name', $name));         $root->appendChild(             $this->createElementNS($this->ns, 'id', $id'));     } 

All Atom elements live under the http://www.w3.org/2005/Atom XML namespace. Therefore, all atom1 methods use DOMDocument::createElementNS( ), which is the namespace version of DOMDocument::createElement( ). The Atom namespace is stored in atom1::ns, so it's easy to access.

The constructor now takes four arguments: title, link, author name, and feed ID. The title and id are defined similar to RSS channel elements. However, the link is actually set as the href attribute of the link element, and the name is a child of the author element.

Additionally, there is an updated element, which is set to the last update time. In this case, it's set to the current time and formatted using PHP's built-in DATE_ATOM constant formatting specification. This is only available as of PHP 5.1.1; if you're using an earlier version of PHP, substitute the string Y-m-d\\TH:i:sP.

The addItem( ) method is renamed to addEntry( ) to be consistent with the Atom specification:

     public function addEntry($title, $link, $summary, $id) {         $entry = $this->createElementNS($this->ns, 'entry');         $entry->appendChild(             $this->createElementNS($this->ns, 'title', $title));         $entry->appendChild(             $this->createElementNS($this->ns, 'link', $link));         $entry->appendChild(             $this->createElementNS($this->ns, 'id', $id));         $entry->appendChild(             $this->createElementNS($this->ns, 'updated', date(DATE_ATOM)));         $entry->appendChild(             $this->createElementNS($this->ns, 'summary', $summary));         $this->documentElement->appendChild($entry);     } 

It behaves very similar to its counterpart, with the few additions of new elements, such as id and updated.

Everything comes together like this:

$atom = new atom1('Channel Title', 'http://www.example.org',                 'John Quincy Atom', 'http://example.org/atom/feed/ids/1'); $atom->addEntry('Item 1', 'http://www.example.org/item1',               'Item 1 Description', 'http://example.org/atom/entry/ids/1'); $atom->addEntry('Item 2', 'http://www.example.org/item2',               'Item 2 Description', 'http://example.org/atom/entry/ids/2'); print $atom->saveXML();

<?xml version="1.0"?> <feed xmlns="http://www.w3.org/2005/Atom">   <title>Channel Title</title>   <link href="http://www.example.org"/>   <updated>2006-10-23T22:33:59-07:00</updated>   <author>     <name>John Quincy Atom</name>   </author>   <id>http://example.org/atom/feed/ids/1</id>   <entry>     <title>Item 1</title>     <link>http://www.example.org/item1</link>     <id>http://example.org/atom/entry/ids/1</id>     <updated>2006-10-23T20:23:32-07:00</updated>     <summary>Item 1 Description</summary>   </entry>   <entry>     <title>Item 2</title>     <link>http://www.example.org/item2</link>     <id>http://example.org/atom/entry/ids/2</id>     <updated>2006-10-23T21:53:44-07:00</updated>     <summary>Item 2 Description</summary>   </entry> </feed>

Like the rss2 class, atom1 implements only a small subset of the full specification. It's enough to generate a valid feed, but if you need to do more, then you will need to extend the class.

12.14.4. See Also

The Atom home page http://www.atomenabled.org/; the Atom Wiki at http://www.intertwingly.net/wiki/pie/; more information on Atom at http://en.wikipedia.org/wiki/Atom_(standard) .




PHP Cookbook, 2nd Edition
PHP Cookbook: Solutions and Examples for PHP Programmers
ISBN: 0596101015
EAN: 2147483647
Year: 2006
Pages: 445

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net