1: <?php
2: 3: 4: 5: 6: 7: 8: 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: 19: 20: 21: 22: 23: 24: 25: 26:
27:
28: class AtomXHTMLContent {
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: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 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' );
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:
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',
159: new XMLElement('generator', 'DAViCal', array('uri' => 'https://www.davical.org/', 'version' => $c->version_string ) )
160: );
161: }
162:
163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 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: 199: 200: 201: 202: 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: