Overview

Packages

  • awl
    • caldav-client-v2
    • RRule
  • davical
    • authentication
      • drivers
    • caldav
    • DAViCalSession
    • DAVTicket
    • external-bind
    • feed
    • HTTPAuthSession
    • iSchedule
    • iSchedule-POST
    • logging
    • metrics
    • Principal
    • propfind
    • PublicSession
    • Request
    • Resource
    • tzservice
  • None
  • PHP

Classes

  • AtomEntry
  • AtomFeed
  • AtomXHTMLContent

Functions

  • caldav_get_feed
  • hyperlink
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: /**
  3:  * Atom feed of recent changes to a calendar collection
  4:  *
  5:  * @package davical
  6:  * @subpackage feed
  7:  * @author Andrew McMillan <andrew@morphoss.com>
  8:  * @license GPL v2 or later
  9:  */
 10: 
 11: require_once("XMLDocument.php");
 12: 
 13: define('ATOM_XMLNS','http://www.w3.org/2005/Atom');
 14: define('XHTML_XMLNS','http://www.w3.org/1999/xhtml');
 15: 
 16: 
 17: /**
 18:  * These two classes here sort of emulate the interface from the  Zend Framework API
 19:  * with regard to ZendFeedWriteFeed for constructing an Atom feed.  Except we do it
 20:  * in a DAViCal way, and we have some huge limitations:
 21:  *  - We *only* support Atom feeds.
 22:  *  - We *only* support creating them.
 23:  *
 24:  * @author Andrew McMillan <andrew@morphoss.com>
 25:  *
 26:  */
 27: 
 28: class AtomXHTMLContent /* extends XMLElement */ {
 29:    private $content_string;
 30: 
 31:    function __construct($xhtml) {
 32:      $this->content_string = $xhtml;
 33:    }
 34: 
 35:    function Render( $ignore1, $ignore2, $ignore3 ) {
 36:      return $this->content_string . "\n";
 37:    }
 38: }
 39: 
 40: 
 41: class AtomEntry {
 42:   /**
 43:   <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
 44:     <title type="html"><![CDATA[Woohoo!  Time to Par-tay! (1/1)]]></title>
 45: 
 46:     <summary type="html"><![CDATA[Have a microparty. All the best parties are monthly!]]></summary>
 47:     <published>2008-10-25T11:07:49+13:00</published>
 48:     <updated>2010-12-27T06:49:16+13:00</updated>
 49:     <id>http://mycaldav/feed.php/user1/home/MICROPARTY-77C6-4FB7-BDD3-6882E2F1BE74.ics#UID:MICROPARTY-77C6-4FB7-BDD3-6882E2F1BE74</id>
 50:     <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
 51:       <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:strong>Time:</xhtml:strong> 2008-11-21 16:00:00<xhtml:br/><xhtml:br/><xhtml:strong>Description</xhtml:strong>:<xhtml:br/>Have a microparty. All the best parties are monthly!</xhtml:div>
 52: 
 53:     </content>
 54:   </entry>
 55:   */
 56:   private $id;
 57:   private $title;
 58:   private $updated;
 59:   private $nodes;
 60: 
 61:   function __construct( $id, $title, $published, $updated ) {
 62:     $this->nodes = array( 'id', 'title', 'updated' );  // placeholders
 63:   }
 64: 
 65:   public function setId( $new_value ) {
 66:     $this->id = new XMLElement('id', rtrim($new_value,"\r\n"));
 67:     return $this->id;
 68:   }
 69: 
 70:   public function setTitle( $new_value, $type = 'text' ) {
 71:     $this->title = new XMLElement('title', $new_value, array( 'type' => $type ));
 72:     return $this->title;
 73:   }
 74: 
 75:   public static function setDate( $tagname, $epoch ) {
 76:     // e.g. 2010-12-26T17:49:16+13:00
 77:     return new XMLElement($tagname, date('Y-m-d\TH:i:sP',$epoch));
 78:   }
 79: 
 80:   public function setDateModified( $epoch ) {
 81:     $this->updated = self::setDate('updated', $epoch);
 82:     return $this->updated;
 83:   }
 84: 
 85:   public function setDateCreated( $epoch ) {
 86:     $node = self::setDate('published', $epoch);
 87:     $this->nodes[] = $node;
 88:     return $node;
 89:   }
 90: 
 91:   public function setLink( $new_value, $type="text/calendar", $rel='alternate' ) {
 92:     return $this->addNode('link', $new_value, array( 'rel' => $rel, 'type' => $type ) );
 93:   }
 94: 
 95:   public function addAuthor( $new_value ) {
 96:     if ( is_array($new_value) && isset($new_value['name']) ) {
 97:       $author = $this->addNode('author' );
 98:       foreach( $new_value AS $k => $v ) {
 99:         $author->NewElement($k, $v);
100:       }
101:       return $author;
102:     }
103:     throw new Exception("AtomFeed::addAuthor(\$new_value) the \$new_value MUST be an array with at least a 'name' element. RFC4287-3.2");
104:   }
105: 
106: 
107:   public function addCategory( $new_value ) {
108:     if ( is_array($new_value) && isset($new_value['term']) ) {
109:       $category = $this->addNode('category', null, $new_value );
110:       return $category;
111:     }
112:     throw new Exception("AtomFeed::addCategory(\$new_value) the \$new_value MUST be an array with at least a 'term' element, and potentially a 'scheme' and a 'label' element. RFC4287-4.2.2");
113:   }
114: 
115: 
116:   public function setDescription( $new_value, $type = 'text' ) {
117:     return $this->addNode('summary', $new_value, array( 'type' => $type ) );
118:   }
119: 
120:   public function setContent( $new_value, $type = 'xhtml' ) {
121:     $content = $this->addNode('content', null, array( 'type' => $type ) );
122:     if ( $type == 'xhtml' ) {
123:       $content->NewElement('div', array( new AtomXHTMLContent($new_value) ), array('xmlns' => XHTML_XMLNS));
124:     }
125:     else {
126:       $content->SetContent($new_value);
127:     }
128:     return $content;
129:   }
130: 
131:   public function addNode( $in_tag, $content=false, $attributes=false, $xmlns=null ) {
132:     $node = new XMLElement($in_tag,$content,$attributes,$xmlns);
133:     if ( !isset($node) ) return null;
134:     $this->nodes[] = $node;
135:     return $node;
136:   }
137: 
138:   public function getXML() {
139:     $this->nodes[0] = $this->id;
140:     $this->nodes[1] = $this->title;
141:     $this->nodes[2] = $this->updated;
142:     return $this->nodes;
143:   }
144: }
145: 
146: 
147: class AtomFeed extends XMLDocument {
148: 
149:   private $id;
150:   private $title;
151:   private $updated;
152:   private $nodes;
153: 
154:   public function __construct() {
155:     global $c;
156:     parent::__construct( array( ATOM_XMLNS => null, XHTML_XMLNS => 'xhtml' ) );
157:     $this->title = 'DAViCal Atom Feed';
158:     $this->nodes = array( 'id', 'title', 'updated',  // placeholders
159:         new XMLElement('generator', 'DAViCal', array('uri' => 'https://www.davical.org/', 'version' => $c->version_string ) )
160:       );
161:   }
162: 
163:   /*
164:   <id>http://mycaldav/feed.php/user1/home.ics</id>
165:   <title type="text">CalDAV Feed: User 1's Calendaranza</title>
166:   <updated>2010-12-26T17:49:16+13:00</updated>
167:   <generator uri="http://framework.zend.com" version="1.10.7">Zend_Feed_Writer</generator>
168:   <link rel="alternate" type="text/html" href="http://mycaldav/feed.php/user1/home.ics"/>
169:   <link rel="self" type="application/atom+xml" href="http://mycaldav/feed.php/user1/home/"/>
170:   <author>
171:     <name>User 1</name>
172:     <email>user1@example.net</email>
173:     <uri>http://mycaldav/feed.php/caldav.php/user1/</uri>
174:   </author>
175:   */
176: 
177:   public function setId( $new_value ) {
178:     $this->id = $this->NewXMLElement('id', $new_value);
179:     return $this->id;
180:   }
181: 
182:   public function setTitle( $new_value, $type = 'text' ) {
183:     $this->title = $this->NewXMLElement('title', $new_value, array( 'type' => $type ));
184:     return $this->title;
185:   }
186: 
187:   public function setDateModified( $epoch ) {
188:     $this->updated = AtomEntry::setDate('updated', $epoch);
189:     return $this->updated;
190:   }
191: 
192:   public function setLink( $new_value, $type="text/calendar", $rel='alternate' ) {
193:     return $this->addNode('link', $new_value, array( 'rel' => $rel, 'type' => $type ) );
194:   }
195: 
196: 
197:   /**
198:    * Sets the feed link (rel=self), ignoring the parameter which is for
199:    * compatibility with the Zend library API, although we use this for
200:    * the Id, whereas they use the first link that is set.
201:    * @param uri $new_value The link target
202:    * @return XMLElement the node that was added.
203:    */
204:   public function setFeedLink( $new_value, $type = null ) {
205:     $this->setId($new_value);
206:     return $this->setLink($new_value , 'application/atom+xml', 'self' );
207:   }
208: 
209:   public function addAuthor( $new_value ) {
210:     if ( is_array($new_value) && isset($new_value['name']) ) {
211:       $author = $this->addNode('author' );
212:       foreach( $new_value AS $k => $v ) {
213:         $this->NSElement($author, $k, $v);
214:       }
215:       return $author;
216:     }
217:     throw new Exception("AtomFeed::addAuthor(\$new_value) the \$new_value MUST be an array with at leas a 'name' element. RFC4287-3.2");
218:   }
219: 
220: 
221:   public function setDescription( $new_value, $type = 'text' ) {
222:     return $this->addNode('subtitle', $new_value, array( 'type' => $type ) );
223:   }
224: 
225:   public function addNode( $in_tag, $content=false, $attributes=false, $xmlns=null ) {
226:     $node = $this->NewXMLElement($in_tag,$content,$attributes,$xmlns);
227:     if ( !isset($node) ) return null;
228:     $this->nodes[] = $node;
229:     return $node;
230:   }
231: 
232:   public function addEntry( $new_entry ) {
233:     if ( !isset($new_entry) ) return;
234:     $this->nodes[] = new XMLElement('entry', $new_entry->getXML() );
235:   }
236: 
237:   public function createEntry( $id=null, $title=null, $published=null, $updated=null ) {
238:     return new AtomEntry($id,$title,$published,$updated);
239:   }
240: 
241:   public function export( $format='atom' ) {
242:     if ( $format != 'atom' ) throw new Exception("AtomFeed class only supports creation of Atom 1.0 format feeds.");
243:     $this->nodes[0] = $this->id;
244:     $this->nodes[1] = $this->title;
245:     $this->nodes[2] = $this->updated;
246:     return $this->Render('feed', $this->nodes );
247:   }
248: }
249: 
250: 
DAViCal API documentation generated by ApiGen 2.8.0