Atom Feed Class

This class makes it easy to create an Atom Feed. The official protocol is here (feel free to knock yourself out), but I adhered to the human-readable Atom Syndication Format when developing this class. Also:

You don't have to worry about formatting any of your dates as we do all of that in-house. Any date that can be translated by PHP's strtotime() function will do just fine. After you're done, Validate Your Atom Feed to make sure you got things right. Finally, place the following at the top of every page that corresponds to your Atom Feed so that browsers will recognize it:

$page->link('<link rel="alternate" type="application/atom+xml" href="http://www.your-website.com/atom.xml" title="Your title" />');

object Atom ( string $title, string $id, string $updated )

This is the constructor for the class, and it takes in the three required feed elements to get your Atom feed on it's feet.

$title The name of your Atom feed.
$id A unique and permanent id. Your website will be just fine.
$updated The last time the feed was modified in a significant way.
Returns An Atom object.
Example
$atom = new Atom ('My Atom Feed', 'http://www.website.com/', 'yesterday');

feed ( array $elements )

This method allows you to insert all of the other recommended, and optional feed elements into your feed. See the examples below. You don't have to keep calling this method for every element, you can just throw everything into an array and call the method only once.

$elements Key and value pairs of feed elements, and their values.
'author', and 'link' are recommended. All others are optional.
Example
$atom->feed(array('author'=>array('name'=>'John Doe'), 
                  'link'=>array('rel'=>'self', 
                                'type'=>'application/atom+xml', 
                                'href'=>'http://www.website.com/atom.xml') 
                  ));

author

The author of the feed. The author must either be defined here, or in every entry.

name (required) The author's name.
email (optional) The author's email address.
uri (optional) The author's home page.
Example
$elements['author'] = array('name'=>'John Doe', 
                            'email'=>'JohnDoe@example.com', 
                            'uri'=>'http://example.com/~johndoe');

link

A related webpage. It is recommended that you include this in your feed, and have it link to the feed itself.

href (required) The URI (or web page).
rel (optional)
'alternate' (the default) An alternate representation of the feed.
'enclosure' - Resource is huge and may require special handling.
'related' - The identified resource is related.
'self' - The feed itself.
'via' - The source of the information.
type (optional) The media type.
hreflang (optional) The language.
title (optional) The title.
length (optional) The length of the resource in bytes.
Example
$elements['link'] = array('href'=>'http://www.website.com/atom.xml', 
                          'rel'=>'self');

category

An appropriate category for the feed.

term (required) The category.
label (optional) A human-readable verision of 'term' (if different).
scheme (optional) The URI categorization scheme.
Example
$elements['category'] = array('term'=>'news', 
                              'label'=>'News', 
                              'scheme'=>'http://www.website.com/tags/');

contributor

A contributor to the feed.

name (required) The contributor's name.
email (optional) The contributor's email address.
uri (optional) The contributor's home page.
Example
$elements['contributor'] = array('name'=>'Jane Doe', 
                            'email'=>'JaneDoe@example.com', 
                            'uri'=>'http://example.com/~janedoe');

generator

Any software kudos you would like to give. The 'uri' and 'version' elements are optional.

Example
$elements['generator'] = 'PHP-Ease.com Atom Feed Class'; // or ... 
$elements['generator'] = array('value'=>'PHP-Ease.com Atom Feed Class', 
                               'version'=>'1.0', 
                               'uri'=>'http://www.php-ease.com/classes/atom-feed.html');

icon

An icon image for the feed. It should be square and small.

Example
$elements['icon'] = 'http://www.website.com/icon.jpg';

logo

A logo for the feed. It should twice as wide as it is tall.

Example
$elements['logo'] = 'http://www.website.com/logo.jpg';

rights

A copyright notice for the feed.

Example
$elements['rights'] = 'Copyright 2010 Website';

subtitle

A subtitle for the feed.

Example
$elements['subtitle'] = 'My website tagline.';

entry ( string $title, string $id, string $updated [, array $elements ] )

This method creates an entry in your feed. All of the required fields are required by the method. The only exception is if you did not indicate an author in the feed, then you must do so with every entry.

$title The title of the entry.
$id A unique and permanent id for the feed entry.
$updated The last time the entry was modified in a significant way.
$elements Key and value pairs of entry elements, and their values. See below for examples.
Example
$atom->entry('Entry Title', 
             'http://www.website.com/link.html', 
             '2004-08-15 16:23:42', 
             array('link'=>array('rel'=>'alternate', 
                                 'href'=>'http://www.website.com/link.html'), 
                   'summary'=>'Some text.'));

author

The author of the entry. If the author is not defined in the feed, then it must be defined here in every entry.

name (required) The author's name.
email (optional) The author's email address.
uri (optional) The author's home page.
Example
$elements['author'] = array('name'=>'John Doe', 
                            'email'=>'JohnDoe@example.com', 
                            'uri'=>'http://example.com/~johndoe');

content

The complete content of the entry. This must be provided if there is no 'alternate' link, and should be provided if there is no 'summary'.

type (optional)
'text' (the default) - Plain old, same old.
'html' - To use html, run your content through htmlspecialchars().
'xhtml' - To use xhtml, keep your content how it is and wrap it in div tags like so:
<div xmlns="http://www.w3.org/1999/xhtml">AT&amp;T bought <b>by SBC</b>!</div>
Example
$elements['content'] = 'Complete story here.'; // or ... 
$elements['content'] = array('type'=>'xhtml', 
                             'value'=>'<div xmlns="http://www.w3.org/1999/xhtml">AT&amp;T bought <b>by SBC</b>!</div>');

link

A related webpage. If the 'content' element is not defined, then the 'link' must be.

href (required) The URI (or web page).
rel (optional)
'alternate' (the default) An alternate representation of the entry.
'enclosure' - Resource is huge and may require special handling.
'related' - The identified resource is related.
'self' - The feed itself.
'via' - The source of the information.
type (optional) The media type.
hreflang (optional) The language.
title (optional) The title.
length (optional) The length of the resource in bytes.
Example
$elements['link'] = array('rel'=>'alternate', 
                          'href'=>'http://www.website.com/link.html');

summary

A short summary of the entry. This should be provided if the 'content' is not.

type (optional)
'text' (the default) - Plain old, same old.
'html' - To use html, run your summary through htmlspecialchars().
'xhtml' - To use xhtml, keep your summary how it is and wrap it in div tags like so:
<div xmlns="http://www.w3.org/1999/xhtml">AT&amp;T bought <b>by SBC</b>!</div>
Example
$elements['summary'] = 'Some text.'; // or ... 
$elements['summary'] = array('type'=>'xhtml', 
                             'value'=>'<div xmlns="http://www.w3.org/1999/xhtml">AT&amp;T bought <b>by SBC</b>!</div>');

category

An appropriate category for the entry.

term (required) The category.
label (optional) A human-readable verision of 'term' (if different).
scheme (optional) The URI categorization scheme.
Example
$elements['category'] = array('term'=>'news', 
                              'label'=>'News', 
                              'scheme'=>'http://www.website.com/tags/');

contributor

A contributor to the entry.

name (required) The contributor's name.
email (optional) The contributor's email address.
uri (optional) The contributor's home page.
Example
$elements['contributor'] = array('name'=>'Jane Doe', 
                            'email'=>'JaneDoe@example.com', 
                            'uri'=>'http://example.com/~janedoe');

published

The date the entry was first published.

Example
$elements['published'] = '2000-01-01';

source

If your entry is copied from another feed, then that feed's elements should be included here (except it's entry elements).

Example
$elements['source'] = array('id'=>'http://www.otherfeed.com/', 
                            'title'=>'Other Feed', 
                            'updated'=>'2003-12-13T18:30:02Z', 
                            'rights'=>'Copyright 2005 Other Feed, Inc.');

rights

A copyright notice for the feed.

type (optional)
'text' (the default) - Plain old, same old.
'html' - To use html, run your copyright through htmlspecialchars().
'xhtml' - To use xhtml, keep your copyright how it is and wrap it in div tags like so:
<div xmlns="http://www.w3.org/1999/xhtml">&copy; 2010 Website</div>
Example
$elements['rights'] = 'Copyright 2010 Website'; // or ... 
$elements['rights'] = array('type'=>'xhtml', 
                            'value'=>'<div xmlns="http://www.w3.org/1999/xhtml">&copy; 2010 Website</div>');

display ( )

This method puts the whole Atom Feed together, sets the appropriate header, echo's the xml, then exits the script.

Example
$atom->display();
Click to Download the PHP Atom Feed Class

 Subscribe to our feed

Atom.php

<?php 
 
/* 
 *    author:           Kyle Gadd 
 *    documentation:    http://www.php-ease.com/classes/atom-feed.html 
 * 
 *    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/>. 
 */ 
 
class Atom { 
 
  public $encoding = 'utf-8'; 
  private $feed = array(); 
  private $entries = array(); 
 
  public function __construct ($title, $id, $updated) { 
    $this->feed['title'] = $title; 
    $this->feed['id'] = $id; 
    $this->feed['updated'] = $updated; 
  } 
   
  public function feed ($elements) { 
    foreach ($elements as $key => $value) $this->feed[$key] = $value; 
  } 
   
  public function entry ($title, $id, $updated, $elements) { 
    $entry = array(); 
    $entry['title'] = $title; 
    $entry['id'] = $id; 
    $entry['updated'] = $updated; 
    foreach ($elements as $key => $value) $entry[$key] = $value; 
    $this->entries[] = $entry; 
  } 
   
  public function display () { 
    $xml = '<?xml version="1.0" encoding="' . $this->encoding . '"?>' . "\n"; 
    $xml .= '<feed xmlns="http://www.w3.org/2005/Atom">' . "\n"; 
    foreach ($this->feed as $key => $value) $xml .= '  ' . $this->tag($key, $value) . "\n"; 
    foreach ($this->entries as $entry) { 
      $xml .= "  <entry>\n"; 
      foreach ($entry as $key => $value) $xml .= '    ' . $this->tag($key, $value) . "\n"; 
      $xml .= "  </entry>\n"; 
    } 
    $xml .= '</feed>'; 
    header("Content-Type: application/atom+xml"); 
    echo $xml; 
    exit; 
  } 
   
  private function tag ($key, $values) { 
    $tag = ''; 
    list($value, $attributes) = $this->values($values); 
    if (in_array($key, array('updated', 'published'))) $value = $this->date($value); 
    if ($key == 'author' || $key == 'contributor') { 
      $tag .= '<' . $key . '>'; 
        $tag .= '<name>' . $values['name'] . '</name>'; // either the feed, or all of the entries mush have an author element 
        if (isset($values['email'])) $tag .= '<email>' . $values['email'] . '</email>'; 
        if (isset($values['uri'])) $tag .= '<uri>' . $values['uri'] . '</uri>'; 
      $tag .= '</' . $key . '>'; 
    } elseif ($key == 'category') { 
      $tag .= '<' . $key . ' term="'; 
      $tag .= (isset($values['term'])) ? $values['term'] : $value; 
      $tag .= '"'; 
      if (isset($values['scheme'])) $tag .= ' scheme="' . $values['scheme'] . '"'; 
      if (isset($values['label'])) $tag .= ' label="' . $values['label'] . '"'; 
      $tag .= ' />'; 
    } elseif ($key == 'source') { 
      $tag .= '<' . $key . '>'; 
        $tag .= '<id>' . $values['id'] . '</id>'; 
        $tag .= '<title>' . $values['email'] . '</title>'; 
        $tag .= '<updated>' . $values['uri'] . '</updated>'; 
        $tag .= '<rights>' . $values['rights'] . '</rights>'; 
      $tag .= '</' . $key . '>'; 
    } else { 
      if (!empty($value)) { 
        $tag .= '<' . $key . $attributes . '>' . $value . '</' . $key . '>'; 
      } else { 
        $tag .= '<' . $key . $attributes . ' />'; 
      } 
    } 
    return $tag; 
  } 
   
  private function values ($array) { 
    if (!is_array($array)) return array($array, ''); 
    $value = (isset($array['value'])) ? $array['value'] : ''; 
    unset ($array['value']); 
    $attributes = ''; 
    foreach ($array as $k => $v) { 
      $attributes .= " {$k}=\"" . addslashes($v) . '"'; 
    } 
    return array($value, $attributes); 
  } 
   
  private function date ($date) { 
    return date(DATE_ATOM, strtotime($date)); 
  } 
 
} 
 
?>

comments powered by Disqus
Copyright © 2011 PHP-Ease.com - PHP Made Easy