## Apache Zeta Components Manual :: File Source for atom.php

## Source for file atom.php

Documentation is available at atom.php

1. <?php
2. /**
3. * File containing the ezcFeedAtom class.
4. *
5. * Licensed to the Apache Software Foundation (ASF) under one
6. * or more contributor license agreements. See the NOTICE file
7. * distributed with this work for additional information
8. * regarding copyright ownership. The ASF licenses this file
9. * to you under the Apache License, Version 2.0 (the
10. * "License"); you may not use this file except in compliance
11. * with the License. You may obtain a copy of the License at
12. *
13. * http://www.apache.org/licenses/LICENSE-2.0
14. *
15. * Unless required by applicable law or agreed to in writing,
16. * software distributed under the License is distributed on an
17. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18. * KIND, either express or implied. See the License for the
19. * specific language governing permissions and limitations
20. * under the License.
21. *
22. * @package Feed
23. * @version //autogentag//
24. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
25. * @filesource
26. */
28. /**
29. * Class providing parsing and generating of ATOM feeds.
30. *
31. * Specifications:
32. * {@link http://atompub.org/rfc4287.html ATOM RFC4287}.
33. *
34. * @package Feed
35. * @version //autogentag//
36. */
37. class ezcFeedAtom extends ezcFeedProcessor implements ezcFeedParser
38. {
39. /**
40. * Defines the feed type of this processor.
41. */
42. const FEED_TYPE = 'atom';
44. /**
45. * Defines the feed content type of this processor.
46. */
47. const CONTENT_TYPE = 'application/atom+xml';
49. /**
50. * Defines the namespace for ATOM feeds.
51. */
52. const NAMESPACE_URI = 'http://www.w3.org/2005/Atom';
54. /**
55. * Creates a new ATOM processor.
56. *
57. * @param ezcFeed $container The feed data container used when generating
58. */
59. public function __construct ( ezcFeed $container )
60. {
61. $this->feedContainer = $container;
62. $this->feedType = self::FEED_TYPE;
63. $this->contentType = self::CONTENT_TYPE;
64. }
66. /**
67. * Returns an XML string from the feed information contained in this
68. * processor.
69. *
70. * @return string
71. */
72. public function generate ()
73. {
74. $this->xml = new DOMDocument( '1.0', 'utf-8' );
75. $this->xml->formatOutput = 1;
77. $rss = $this->xml->createElementNS( self::NAMESPACE_URI, 'feed' );
78. $this->channel = $rss;
79. $this->root = $this->xml->appendChild( $rss );
81. $this->generateRequired();
82. $this->generateAtLeastOne();
83. $this->generateOptional();
84. $this->generateFeedModules( $this->channel );
85. $this->generateItems();
87. return $this->xml->saveXML();
88. }
90. /**
91. * Returns true if the parser can parse the provided XML document object,
92. * false otherwise.
93. *
94. * @param DOMDocument $xml The XML document object to check for parseability
95. * @return bool
96. */
97. public static function canParse ( DOMDocument $xml )
98. {
99. if ( $xml->documentElement->tagName !== 'feed' )
100. {
101. return false;
102. }
104. return true;
105. }
107. /**
108. * Parses the provided XML document object and returns an ezcFeed object
109. * from it.
110. *
111. * @throws ezcFeedParseErrorException
112. * If an error was encountered during parsing.
113. *
114. * @param DOMDocument $xml The XML document object to parse
115. * @return ezcFeed
116. */
117. public function parse ( DOMDocument $xml )
118. {
119. $feed = new ezcFeed ( self::FEED_TYPE );
120. $channel = $xml->documentElement;
122. $this->usedPrefixes = $this->fetchUsedPrefixes( $xml );
124. foreach ( $channel->childNodes as $channelChild )
125. {
126. if ( $channelChild->nodeType == XML_ELEMENT_NODE )
127. {
128. $tagName = $channelChild->tagName;
130. switch ( $tagName )
131. {
132. case 'title':
133. $this->parseTextNode( $feed, $channelChild, 'title' );
134. break;
136. case 'rights':
137. $this->parseTextNode( $feed, $channelChild, 'copyright' );
138. break;
140. case 'subtitle':
141. $this->parseTextNode( $feed, $channelChild, 'description' );
142. break;
144. case 'id':
145. $feed->$tagName = $channelChild->textContent;
146. break;
148. case 'icon':
149. $feed->$tagName = $channelChild->textContent;
150. break;
152. case 'logo':
153. $feed->image = $channelChild->textContent;
154. break;
156. case 'generator':
157. $element = $feed->add( $tagName );
159. $attributes = array( 'uri' => 'url', 'version' => 'version' );
160. foreach ( $attributes as $name => $alias )
161. {
162. if ( $channelChild->hasAttribute( $name ) )
163. {
164. $element->$alias = $channelChild->getAttribute( $name );
165. }
166. }
167. $element->name = $channelChild->textContent;
168. break;
170. case 'updated':
171. $feed->$tagName = $channelChild->textContent;
172. break;
174. case 'category':
175. $element = $feed->add( $tagName );
177. $attributes = array( 'term' => 'term', 'scheme' => 'scheme', 'label' => 'label' );
178. foreach ( $attributes as $name => $alias )
179. {
180. if ( $channelChild->hasAttribute( $name ) )
181. {
182. $element->$alias = $channelChild->getAttribute( $name );
183. }
184. }
185. break;
187. case 'link':
188. $element = $feed->add( $tagName );
190. $attributes = array( 'href' => 'href', 'rel' => 'rel', 'hreflang' => 'hreflang',
191. 'type' => 'type', 'title' => 'title', 'length' => 'length' );
193. foreach ( $attributes as $name => $alias )
194. {
195. if ( $channelChild->hasAttribute( $name ) )
196. {
197. $element->$alias = $channelChild->getAttribute( $name );
198. }
199. }
200. break;
202. case 'contributor':
203. case 'author':
204. $element = $feed->add( $tagName );
205. $this->parsePerson( $element, $channelChild, $tagName );
206. break;
208. case 'entry':
209. $element = $feed->add( 'item' );
210. $this->parseItem( $element, $channelChild );
211. break;
213. default:
214. // check if it's part of a known module/namespace
215. $this->parseModules( $feed, $channelChild, $tagName );
216. break;
217. }
218. }
219. }
221. if ( $channel->hasAttribute( 'xml:lang' ) )
222. {
223. $feed->language = $channel->getAttribute( 'xml:lang' );
224. }
226. return $feed;
227. }
229. /**
230. * Adds the required feed elements to the XML document being generated.
231. */
232. private function generateRequired()
233. {
234. $elements = array( 'id', 'title', 'updated' );
235. foreach ( $elements as $element )
236. {
237. $data = $this->$element;
238. if ( is_null ( $data ) )
239. {
240. throw new ezcFeedRequiredMetaDataMissingException ( "/feed/{$element}" );
241. }
243. switch ( $element )
244. {
245. case 'id':
246. $this->generateMetaData( $this->channel, $element, $data );
247. break;
249. case 'title':
250. $this->generateTextNode( $this->channel, $element, $data );
251. break;
253. case 'updated':
254. // Sample date: 2003-12-13T18:30:02-05:00
255. $this->generateMetaData( $this->channel, $element, $data->date->format( 'c' ) );
256. break;
258. }
259. }
260. }
262. /**
263. * Adds the at-least-one feed elements to the XML document being generated.
264. */
265. private function generateAtLeastOne()
266. {
267. $needToThrowException = false;
268. $element = 'author';
270. $data = $this->$element;
272. if ( is_null ( $data ) )
273. {
274. $entries = $this->item;
275. if ( $entries === null )
276. {
277. throw new ezcFeedAtLeastOneItemDataRequiredException ( array( '/feed/author' ) );
278. }
280. foreach ( $entries as $entry )
281. {
282. $authors = $entry->author;
283. if ( $authors === null )
284. {
285. throw new ezcFeedAtLeastOneItemDataRequiredException ( array( '/feed/entry/author' ) );
286. }
287. }
289. throw new ezcFeedAtLeastOneItemDataRequiredException ( array( '/feed/author' ) );
290. }
291. }
293. /**
294. * Adds the optional feed elements to the XML document being generated.
295. */
296. private function generateOptional()
297. {
298. $elements = array( 'author', 'link', 'category',
299. 'contributor', 'generator', 'icon',
300. 'image', 'copyright', 'description', 'language' );
302. if ( $this->link !== null )
303. {
304. $this->checkLinks( $this->channel, $this->link );
305. }
307. foreach ( $elements as $element )
308. {
309. $data = $this->$element;
311. if ( ! is_null ( $data ) )
312. {
313. switch ( $element )
314. {
315. case 'contributor':
316. foreach ( $this->contributor as $person )
317. {
318. $this->generatePerson( $this->channel, 'contributor', $person );
319. }
320. break;
322. case 'author':
323. foreach ( $this->author as $person )
324. {
325. $this->generatePerson( $this->channel, 'author', $person );
326. }
327. break;
329. case 'generator':
330. $this->generateGenerator( $this->channel, $this->generator );
331. break;
333. case 'link':
334. foreach ( $data as $dataNode )
335. {
336. $this->generateLink( $this->channel, $dataNode );
337. }
338. break;
340. case 'category':
341. foreach ( $data as $dataNode )
342. {
343. $this->generateCategory( $this->channel, $dataNode );
344. }
345. break;
347. case 'description':
348. $this->generateTextNode( $this->channel, 'subtitle', $data );
349. break;
351. case 'copyright':
352. $this->generateTextNode( $this->channel, 'rights', $data );
353. break;
355. case 'image':
356. $this->generateMetaData( $this->channel, 'logo', $data );
357. break;
359. case 'icon':
360. $this->generateMetaData( $this->channel, 'icon', $data );
361. break;
363. case 'language':
364. $this->generateLanguage( $this->channel, $data );
365. break;
366. }
367. }
368. }
369. }
371. /**
372. * Checks if the links are defined correctly.
373. *
374. * @throws ezcFeedOnlyOneValueAllowedException
375. * if there was more than one @rel="alternate" element in the $links array
376. *
377. * @param DOMNode $root The root in which to check the link elements
378. * @param array(ezcFeedLinkElement) $links The link elements to check
379. * @return bool
380. */
381. private function checkLinks( DOMNode $root, array $links )
382. {
383. $unique = array();
384. foreach ( $links as $dataNode )
385. {
386. if ( ( isset( $dataNode->rel ) && $dataNode->rel === 'alternate' )
387. && isset( $dataNode->type )
388. && isset( $dataNode->hreflang ) )
389. {
390. foreach ( $unique as $obj )
391. {
392. if ( $obj['type'] === $dataNode->type
393. && $obj['hreflang'] === $dataNode->hreflang )
394. {
395. $parentNode = ( $root->nodeName === 'entry' ) ? '/feed' : '';
396. $parentNode = ( $root->nodeName === 'source' ) ? '/feed/entry' : $parentNode;
398. throw new ezcFeedOnlyOneValueAllowedException ( "{$parentNode}/{$root

->nodeName}/link@rel=\"alternate\"" );
- }
- }
- $unique[] = array( 'type' => $dataNode->type,
- 'hreflang' => $dataNode->hreflang );
- }
- }
- return true;
- }
- /**
- * Creates a link node in the XML document being generated.
- *
- * @param DOMNode $root The root in which to create the link
- * @param ezcFeedLinkElement $dataNode The data for the link node to create
- */
- private function generateLink( DOMNode $root, ezcFeedLinkElement $dataNode )
- {
- $elementTag = $this->xml->createElement( 'link' );
- $root->appendChild( $elementTag );
- $elements = array( 'href', 'rel', 'type', 'hreflang', 'title', 'length' );
- if ( !isset( $dataNode->href ) )
- {
- $parentNode = ( $root->nodeName === 'entry' ) ? '/feed' : '';
- $parentNode = ( $root->nodeName === 'source' ) ? '/feed/entry' : $parentNode;
- throw new ezcFeedRequiredMetaDataMissingException ( "{$parentNode}/{$root->nodeName}/link/@href" );
- }
- foreach ( $elements as $attribute )
- {
- if ( isset( $dataNode->$attribute ) )
- {
- $this->addAttribute( $elementTag, $attribute, $dataNode->$attribute );
- }
- }
- }
- /**
- * Creates a generator node in the XML document being generated.
- *
- * @param DOMNode $root The root in which to create the generator node
- * @param ezcFeedGeneratorElement $generator The data for the generator node to create
- */
- private function generateGenerator( DOMNode $root, ezcFeedGeneratorElement $generator )
- {
- $name = $generator->name;
- $version = $generator->version;
- $url = $generator->url;
- $elementTag = $this->xml->createElement( 'generator', $name );
- $root->appendChild( $elementTag );
- if ( $version !== null )
- {
- $this->addAttribute( $elementTag, 'version', $version );
- }
- if ( $url !== null )
- {
- $this->addAttribute( $elementTag, 'uri', $url );
- }
- }
- /**
- * Creates a category node in the XML document being generated.
- *
- * @throws ezcFeedRequiredMetaDataMissingException
- * if the required attributes are missing
- *
- * @param DOMNode $root The root in which to create the category node
- * @param ezcFeedCategoryElement $dataNode The data for the category node to create
- */
- private function generateCategory( DOMNode $root, ezcFeedCategoryElement $dataNode )
- {
- $elementTag = $this->xml->createElement( 'category' );
- $root->appendChild( $elementTag );
- $parentNode = ( $root->nodeName === 'entry' ) ? '/feed' : '';
- $parentNode = ( $root->nodeName === 'source' ) ? '/feed/entry' : $parentNode;
- $attributes = array( 'term' => 'term', 'scheme' => 'scheme', 'label' => 'label' );
- $required = array( 'term' );
- $optional = array( 'scheme', 'label' );
- foreach ( $attributes as $attribute => $alias )
- {
- if ( isset( $dataNode->$alias ) )
- {
- $val = $dataNode->$alias;
- $this->addAttribute( $elementTag, $attribute, $val );
- }
- else if ( in_array ( $attribute, $required ) )
- {
- throw new ezcFeedRequiredMetaDataMissingException ( "{$parentNode}/{$root->nodeName}/category/@{$attribute}" );
- }
- }
- }
- /**
- * Creates an XML node in the XML document being generated.
- *
- * @param DOMNode $root The root in which to create the node $element
- * @param string $element The name of the node to create
- * @param ezcFeedTextElement $dataNode The data for the node to create
- */
- private function generateTextNode( DOMNode $root, $element, ezcFeedTextElement $dataNode )
- {
- $elementTag = $this->xml->createElement( $element );
- $root->appendChild( $elementTag );
- $attributes = array();
- if ( isset( $dataNode->type ) )
- {
- $val = $dataNode->type;
- switch ( $val )
- {
- case 'html':
- $dataNode->text = htmlspecialchars ( $dataNode->__toString() );
- $this->addAttribute( $elementTag, 'type', $val );
- break;
- case 'xhtml':
- $this->addAttribute( $elementTag, 'type', $val );
- $this->addAttribute( $elementTag, 'xmlns:xhtml', 'http://www.w3.org/1999/xhtml' );
- $xhtmlTag = $this->xml->createElement( 'xhtml:div', $dataNode->__toString() );
- $elementTag->appendChild( $xhtmlTag );
- $elementTag = $xhtmlTag;
- break;
- case 'text':
- // same as the default case
- default:
- $val = 'text';
- $this->addAttribute( $elementTag, 'type', $val );
- break;
- }
- }
- if ( isset( $dataNode->language ) )
- {
- if ( $dataNode->type === 'xhtml' )
- {
- $this->addAttribute( $elementTag->parentNode, 'xml:lang', $dataNode->language );
- }
- else
- {
- $this->addAttribute( $elementTag, 'xml:lang', $dataNode->language );
- }
- }
- $elementTag->nodeValue = $dataNode;
- }
- /**
- * Creates an attribute on an XML node containing the language in it.
- *
- * @param DOMNode $root The root in which to create the attribute
- * @param ezcFeedTextElement $dataNode The data for the node to create
- */
- private function generateLanguage( DOMNode $root, ezcFeedTextElement $dataNode )
- {
- $this->addAttribute( $root, 'xml:lang', $dataNode->text );
- }
- /**
- * Creates an XML node in the XML document being generated.
- *
- * @param DOMNode $root The root in which to create the node $element
- * @param string $element The name of the node to create
- * @param array(string=>mixed) $dataNode The data for the node to create
- */
- private function generateContentNode( DOMNode $root, $element, $dataNode )
- {
- $elementTag = $this->xml->createElement( $element );
- $root->appendChild( $elementTag );
- $attributes = array();
- if ( isset( $dataNode->type ) )
- {
- $val = $dataNode->type;
- switch ( $val )
- {
- case 'html':
- $dataNode->text = htmlspecialchars ( $dataNode->__toString() );
- $this->addAttribute( $elementTag, 'type', $val );
- break;
- case 'xhtml':
- $this->addAttribute( $elementTag, 'type', $val );
- $this->addAttribute( $elementTag, 'xmlns:xhtml', 'http://www.w3.org/1999/xhtml' );
- $xhtmlTag = $this->xml->createElement( 'xhtml:div', $dataNode->__toString() );
- $elementTag->appendChild( $xhtmlTag );
- $elementTag = $xhtmlTag;
- break;
- case 'text':
- $this->addAttribute( $elementTag, 'type', $val );
- break;
- default:
- if ( preg_match ( '@[+/]xml$@', $val ) !== 0 )
- {
- // @todo: implement to assign the text in $dataNode as an XML node into $elementTag
- $this->addAttribute( $elementTag, 'type', $val );
- }
- else if ( substr_compare ( $val, 'text/', 0, 5, true ) === 0 )
- {
- $dataNode->text = htmlspecialchars ( $dataNode->__toString() );
- $this->addAttribute( $elementTag, 'type', $val );
- break;
- }
- else if ( $val !== null )
- {
- // @todo: make 76 and "\n" options?
- $dataNode->text = chunk_split ( base64_encode ( $dataNode->__toString() ), 76, "\n" );
- $this->addAttribute( $elementTag, 'type', $val );
- }
- else
- {
- $val = 'text';
- $this->addAttribute( $elementTag, 'type', $val );
- }
- break;
- }
- }
- if ( $dataNode->src !== null )
- {
- $this->addAttribute( $elementTag, 'src', $dataNode->src );
- }
- if ( $dataNode->language !== null )
- {
- if ( $dataNode->type === 'xhtml' )
- {
- $this->addAttribute( $elementTag->parentNode, 'xml:lang', $dataNode->language );
- }
- else
- {
- $this->addAttribute( $elementTag, 'xml:lang', $dataNode->language );
- }
- }
- $elementTag->nodeValue = $dataNode;
- }
- /**
- * Creates an XML person node in the XML document being generated.
- *
- * @param DOMNode $root The root in which to create the node $element
- * @param string $element The name of the node to create
- * @param ezcFeedPersonElement $feedElement The person feed element (author, contributor)
- */
- private function generatePerson( DOMNode $root, $element, ezcFeedPersonElement $feedElement )
- {
- $elementTag = $this->xml->createElement( $element );
- $root->appendChild( $elementTag );
- $parentNode = ( $root->nodeName === 'entry' ) ? '/feed' : '';
- $parentNode = ( $root->nodeName === 'source' ) ? '/feed/entry' : $parentNode;
- $name = $feedElement->name;
- $email = $feedElement->email;
- $uri = $feedElement->uri;
- if ( ! is_null ( $name ) )
- {
- $this->generateMetaData( $elementTag, 'name', $name );
- }
- else
- {
- throw new ezcFeedRequiredMetaDataMissingException ( "{$parentNode}/{$root->nodeName}/{$element}/name" );
- }
- if ( ! is_null ( $email ) )
- {
- $this->generateMetaData( $elementTag, 'email', $email );
- }
- if ( ! is_null ( $uri ) )
- {
- $this->generateMetaData( $elementTag, 'uri', $uri );
- }
- }
- /**
- * Creates an XML source node in the XML document being generated.
- *
- * @param DOMNode $root The root in which to create the source node
- * @param ezcFeedSourceElement $feedElement The feed source
- */
- private function generateSource( DOMNode $root, ezcFeedSourceElement $feedElement )
- {
- $elementTag = $this->xml->createElement( 'source' );
- $root->appendChild( $elementTag );
- $elements = array( 'id', 'title', 'updated',
- 'author', 'link', 'category',
- 'contributor', 'generator', 'icon',
- 'image', 'copyright', 'description' );
- foreach ( $elements as $child )
- {
- $data = $feedElement->$child;
- if ( ! is_null ( $data ) )
- {
- switch ( $child )
- {
- case 'title':
- $this->generateTextNode( $elementTag, 'title', $data );
- break;
- case 'description':
- $this->generateTextNode( $elementTag, 'subtitle', $data );
- break;
- case 'copyright':
- $this->generateTextNode( $elementTag, 'rights', $data );
- break;
- case 'contributor':
- foreach ( $data as $dataNode )
- {
- $this->generatePerson( $elementTag, 'contributor', $dataNode );
- }
- break;
- case 'author':
- foreach ( $data as $dataNode )
- {
- $this->generatePerson( $elementTag, 'author', $dataNode );
- }
- break;
- case 'generator':
- $this->generateGenerator( $elementTag, $data );
- break;
- case 'link':
- foreach ( $data as $dataNode )
- {
- $this->generateLink( $elementTag, $dataNode );
- }
- break;
- case 'category':
- foreach ( $data as $dataNode )
- {
- $this->generateCategory( $elementTag, $dataNode );
- }
- break;
- case 'image':
- $this->generateMetaData( $elementTag, 'logo', $data );
- break;
- case 'icon':
- $this->generateMetaData( $elementTag, 'icon', $data );
- break;
- case 'updated':
- // Sample date: 2003-12-13T18:30:02-05:00
- $this->generateMetaData( $elementTag, 'updated', $data-> date ->format( 'c' ) );
- break;
- case 'id':
- $this->generateMetaData( $elementTag, 'id', $data );
- break;
- }
- }
- }
- }
- /**
- * Adds the feed entry elements to the XML document being generated.
- *
- * @throws ezcFeedRequiredMetaDataException
- * if the required elements or attributes are not present
- */
- private function generateItems()
- {
- $entries = $this->item;
- if ( $entries === null )
- {
- return;
- }
- foreach ( $entries as $entry )
- {
- $entryTag = $this->xml->createElement( 'entry' );
- $this->channel->appendChild( $entryTag );
- if ( ! is_null ( $entry->language ) )
- {
- $this->addAttribute( $entryTag, 'xml:lang', $entry->language );
- }
- $elements = array( 'id', 'title', 'updated' );
- foreach ( $elements as $element )
- {
- $data = $entry->$element;
- if ( is_null ( $data ) )
- {
- throw new ezcFeedRequiredMetaDataMissingException ( "/feed/entry/{$element}" );
- }
- switch ( $element )
- {
- case 'id':
- $this->generateMetaData( $entryTag, $element, $data );
- break;
- case 'title':
- $this->generateTextNode( $entryTag, $element, $data );
- break;
- case 'updated':
- // Sample date: 2003-12-13T18:30:02-05:00
- $this->generateMetaData( $entryTag, $element, $data-> date ->format( 'c' ) );
- break;
- }
- }
- // ensure the ATOM rules are applied
- $content = $entry->content;
- $summary = $entry->description;
- $links = $entry-> link ;
- $contentPresent = ! is_null ( $content );
- $contentSrcPresent = $contentPresent && is_object ( $content ) && ! is_null ( $content->src );
- $contentBase64 = true;
- if ( $contentPresent && is_object ( $content )
- && ( in_array ( $content->type, array( 'text', 'html', 'xhtml', null ) )
- || preg_match ( '@[+/]xml$@i', $content->type ) !== 0
- || substr_compare ( $content->type, 'text/', 0, 5, true ) === 0 ) )
- {
- $contentBase64 = false;
- }
- $summaryPresent = ! is_null ( $summary );
- $linkAlternatePresent = false;
- if ( $links !== null )
- {
- foreach ( $links as $link )
- {
- // if the rel attribute is not set or if it is "alternate"
- // then there is at least one rel="alternate" link in the feed entry
- if ( !isset( $link->rel )
- || $link->rel === 'alternate' )
- {
- $linkAlternatePresent = true;
- break;
- }
- }
- }
- if ( !$contentPresent )
- {
- if ( !$linkAlternatePresent && !$summaryPresent )
- {
- throw new ezcFeedRequiredMetaDataMissingException ( '/feed/entry/content' );
- }
- if ( !$linkAlternatePresent )
- {
- throw new ezcFeedRequiredMetaDataMissingException ( '/feed/entry/link@rel="alternate"' );
- }
- if ( !$summaryPresent )
- {
- throw new ezcFeedRequiredMetaDataMissingException ( '/feed/entry/summary' );
- }
- }
- if ( $contentPresent )
- {
- if ( ( $contentSrcPresent || $contentBase64 ) && !$summaryPresent )
- {
- throw new ezcFeedRequiredMetaDataMissingException ( '/feed/entry/summary' );
- }
- }
- $elements = array( 'author', 'content', 'link', 'description',
- 'category', 'contributor', 'published', 'copyright',
- 'source', 'enclosure' );
- if ( $entry-> link !== null )
- {
- $this->checkLinks( $entryTag, $entry-> link );
- }
- foreach ( $elements as $element )
- {
- $data = $entry->$element;
- if ( is_null ( $data ) )
- {
- continue;
- }
- switch ( $element )
- {
- case 'description':
- $this->generateTextNode( $entryTag, 'summary', $data );
- break;
- case 'copyright':
- $this->generateTextNode( $entryTag, 'rights', $data );
- break;
- case 'content':
- $this->generateContentNode( $entryTag, $element, $data );
- break;
- case 'author':
- case 'contributor':
- foreach ( $data as $dataNode )
- {
- $this->generatePerson( $entryTag, $element, $dataNode );
- }
- break;
- case 'link':
- foreach ( $data as $dataNode )
- {
- $this->generateLink( $entryTag, $dataNode );
- }
- break;
- case 'published':
- // Sample date: 2003-12-13T18:30:02-05:00
- $this->generateMetaData( $entryTag, $element, $data-> date ->format( 'c' ) );
- break;
- case 'category':
- foreach ( $data as $dataNode )
- {
- $this->generateCategory( $entryTag, $dataNode );
- }
- break;
- case 'source':
- $this->generateSource( $entryTag, $data );
- break;
- case 'enclosure':
- // convert RSS2 enclosure elements in ATOM link elements
- foreach ( $data as $dataNode )
- {
- $link = new ezcFeedLinkElement ();
- $link->href = $dataNode->url;
- $link->length = $dataNode->length;
- $link->type = $dataNode->type;
- $link->rel = 'enclosure';
- $this->generateLink( $entryTag, $link );
- }
- break;
- }
- }
- $this->generateItemModules( $entry, $entryTag );
- }
- }
- /**
- * Parses the provided XML element object and stores it as a feed item in
- * the provided ezcFeed object.
- *
- * @param ezcFeedEntryElement $element The feed element object that will contain the feed item
- * @param DOMElement $xml The XML element object to parse
- */
- private function parseItem( ezcFeedEntryElement $element, DOMElement $xml )
- {
- foreach ( $xml->childNodes as $itemChild )
- {
- if ( $itemChild->nodeType === XML_ELEMENT_NODE )
- {
- $tagName = $itemChild->tagName;
- switch ( $tagName )
- {
- case 'id':
- $element->$tagName = $itemChild->textContent;
- break;
- case 'title':
- $this->parseTextNode( $element, $itemChild, 'title' );
- break;
- case 'rights':
- $this->parseTextNode( $element, $itemChild, 'copyright' );
- break;
- case 'summary':
- $this->parseTextNode( $element, $itemChild, 'description' );
- break;
- case 'updated':
- case 'published':
- $element->$tagName = $itemChild->textContent;
- break;
- case 'author':
- case 'contributor':
- $subElement = $element->add( $tagName );
- foreach ( $itemChild->childNodes as $subChild )
- {
- if ( $subChild->nodeType === XML_ELEMENT_NODE )
- {
- $subTagName = $subChild->tagName;
- if ( in_array ( $subTagName, array( 'name', 'email', 'uri' ) ) )
- {
- $subElement->$subTagName = $subChild->textContent;
- }
- }
- }
- break;
- case 'content':
- $type = $itemChild->getAttribute( 'type' );
- $src = $itemChild->getAttribute( 'src' );
- $subElement = $element->add( $tagName );
- switch ( $type )
- {
- case 'xhtml':
- $nodes = $itemChild->childNodes;
- if ( $nodes instanceof DOMNodeList )
- {
- for ( $i = 0; $i < $nodes->length; $i++ )
- {
- if ( $nodes->item( $i ) instanceof DOMElement )
- {
- break;
- }
- }
- $contentNode = $nodes->item( $i );
- $subElement->text = $contentNode->nodeValue;
- }
- $subElement->type = $type;
- break;
- case 'html':
- $subElement->text = $itemChild->textContent;
- $subElement->type = $type;
- break;
- case 'text':
- $subElement->text = $itemChild->textContent;
- $subElement->type = $type;
- break;
- case null:
- $subElement->text = $itemChild->textContent;
- break;
- default:
- if ( preg_match ( '@[+/]xml$@i', $type ) !== 0 )
- {
- foreach ( $itemChild->childNodes as $node )
- {
- if ( $node->nodeType === XML_ELEMENT_NODE )
- {
- $doc = new DOMDocument( '1.0', 'UTF-8' );
- $copyNode = $doc->importNode( $node, true );
- $doc->appendChild( $copyNode );
- $subElement->text = $doc->saveXML();
- $subElement->type = $type;
- break;
- }
- }
- }
- else if ( substr_compare ( $type, 'text/', 0, 5, true ) === 0 )
- {
- $subElement->text = $itemChild->textContent;
- $subElement->type = $type;
- break;
- }
- else // base64
- {
- $subElement->text = base64_decode ( $itemChild->textContent );
- $subElement->type = $type;
- }
- break;
- }
- if ( !empty( $src ) )
- {
- $subElement->src = $src;
- }
- $language = $itemChild->getAttribute( 'xml:lang' );
- if ( !empty( $language ) )
- {
- $subElement->language = $language;
- }
- break;
- case 'link':
- $subElement = $element->add( $tagName );
- $attributes = array( 'href' => 'href', 'rel' => 'rel', 'hreflang' => 'hreflang',
- 'type' => 'type', 'title' => 'title', 'length' => 'length' );
- foreach ( $attributes as $name => $alias )
- {
- if ( $itemChild->hasAttribute( $name ) )
- {
- $subElement->$alias = $itemChild->getAttribute( $name );
- }
- }
- break;
- case 'category':
- $subElement = $element->add( $tagName );
- $attributes = array( 'term' => 'term', 'scheme' => 'scheme', 'label' => 'label' );
- foreach ( $attributes as $name => $alias )
- {
- if ( $itemChild->hasAttribute( $name ) )
- {
- $subElement->$alias = $itemChild->getAttribute( $name );
- }
- }
- break;
- case 'source':
- $subElement = $element->add( $tagName );
- $this->parseSource( $subElement, $itemChild );
- break;
- default:
- $this->parseModules( $element, $itemChild, $tagName );
- break;
- }
- }
- }
- if ( $xml->hasAttribute( 'xml:lang' ) )
- {
- $element->language = $xml->getAttribute( 'xml:lang' );
- }
- }
- /**
- * Parses the provided XML element object $xml and stores it as a text element
- *
- * @param ezcFeed|ezcFeedEntryElement$feed The feed object in which to store the parsed XML element as a text element
- * @param DOMElement $xml The XML element object to parse
- * @param string $element The name of the feed element object that will contain the text
- */
- private function parseTextNode( $feed, DOMElement $xml, $element )
- {
- $type = $xml->getAttribute( 'type' );
- switch ( $type )
- {
- case 'xhtml':
- $nodes = $xml->childNodes;
- if ( $nodes instanceof DOMNodeList )
- {
- $contentNode = $nodes->item( 1 );
- $feed->$element = $contentNode->nodeValue;
- }
- break;
- case 'html':
- $feed->$element = $xml->nodeValue;
- break;
- case 'text':
- // same case as 'default'
- default:
- $feed->$element = $xml->nodeValue;
- break;
- }
- if ( $type !== '' )
- {
- $feed->$element->type = $type;
- }
- if ( $xml->hasAttribute( 'xml:lang' ) )
- {
- $feed->$element->language = $xml->getAttribute( 'xml:lang' );
- }
- }
- /**
- * Parses the provided XML element object and stores it as a feed person (author
- * or contributor - based on $type) in the provided ezcFeedPersonElement object.
- *
- * @param ezcFeedPersonElement $element The feed element object that will contain the feed person
- * @param DOMElement $xml The XML element object to parse
- * @param string $type The type of the person (author, contributor)
- */
- private function parsePerson( $element, DOMElement $xml, $type )
- {
- foreach ( $xml->childNodes as $itemChild )
- {
- if ( $itemChild->nodeType === XML_ELEMENT_NODE )
- {
- $tagName = $itemChild->tagName;
- switch ( $tagName )
- {
- case 'name':
- case 'email':
- case 'uri':
- $element->$tagName = $itemChild->textContent;
- break;
- }
- }
- }
- }
- /**
- * Parses the provided XML element object and stores it as a feed source
- * element in the provided ezcFeedSourceElement object.
- *
- * @param ezcFeedSourceElement $element The feed element object that will contain the feed source
- * @param DOMElement $xml The XML element object to parse
- */
- private function parseSource( ezcFeedSourceElement $element, DOMElement $xml )
- {
- foreach ( $xml->childNodes as $sourceChild )
- {
- if ( $sourceChild->nodeType === XML_ELEMENT_NODE )
- {
- $tagName = $sourceChild->tagName;
- switch ( $tagName )
- {
- case 'title':
- $this->parseTextNode( $element, $sourceChild, 'title' );
- break;
- case 'rights':
- $this->parseTextNode( $element, $sourceChild, 'copyright' );
- break;
- case 'subtitle':
- $this->parseTextNode( $element, $sourceChild, 'description' );
- break;
- case 'id':
- $subElement = $element->add( 'id' );
- $subElement->id = $sourceChild->textContent;
- break;
- case 'generator':
- $subElement = $element->add( 'generator' );
- $subElement->name = $sourceChild->textContent;
- $attributes = array( 'uri' => 'url', 'version' => 'version' );
- foreach ( $attributes as $name => $alias )
- {
- if ( $sourceChild->hasAttribute( $name ) )
- {
- $subElement->$alias = $sourceChild->getAttribute( $name );
- }
- }
- break;
- case 'logo':
- $subElement = $element->add( 'image' );
- $subElement-> link = $sourceChild->textContent;
- break;
- case 'icon':
- $subElement = $element->add( 'icon' );
- $subElement-> link = $sourceChild->textContent;
- break;
- case 'updated':
- $element->$tagName = $sourceChild->textContent;
- break;
- case 'category':
- $subElement = $element->add( $tagName );
- $attributes = array( 'term' => 'term', 'scheme' => 'scheme', 'label' => 'label' );
- foreach ( $attributes as $name => $alias )
- {
- if ( $sourceChild->hasAttribute( $name ) )
- {
- $subElement->$alias = $sourceChild->getAttribute( $name );
- }
- }
- break;
- case 'link':
- $subElement = $element->add( $tagName );
- $attributes = array( 'href' => 'href', 'rel' => 'rel', 'hreflang' => 'hreflang',
- 'type' => 'type', 'title' => 'title', 'length' => 'length' );
- foreach ( $attributes as $name => $alias )
- {
- if ( $sourceChild->hasAttribute( $name ) )
- {
- $subElement->$alias = $sourceChild->getAttribute( $name );
- }
- }
- break;
- case 'contributor':
- case 'author':
- $subElement = $element->add( $tagName );
- $this->parsePerson( $subElement, $sourceChild, $tagName );
- break;
- }
- }
- }
- }
- }
- ?>
Documentation generated by phpDocumentor 1.4.3