PageRenderTime 23ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/webapp-php/modules/ezcomponents/libraries/Feed/interfaces/processor.php

https://github.com/AlinT/socorro
PHP | 356 lines | 154 code | 28 blank | 174 comment | 10 complexity | 2d70984fa19486b966758c6e6da12d37 MD5 | raw file
  1. <?php
  2. /**
  3. * File containing the ezcFeedProcessor class.
  4. *
  5. * @package Feed
  6. * @version 1.2.1
  7. * @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
  8. * @license http://ez.no/licenses/new_bsd New BSD License
  9. * @filesource
  10. */
  11. /**
  12. * Base class for all feed processors.
  13. *
  14. * Currently implemented for these feed types:
  15. * - RSS1 ({@link ezcFeedRss1})
  16. * - RSS2 ({@link ezcFeedRss2})
  17. * - ATOM ({@link ezcFeedAtom})
  18. *
  19. * Child classes must implement these methods:
  20. * - generate() - Returns an XML string from the feed information contained.
  21. *
  22. * @package Feed
  23. * @version 1.2.1
  24. */
  25. abstract class ezcFeedProcessor
  26. {
  27. /**
  28. * Holds the feed data container.
  29. *
  30. * @var ezcFeed
  31. * @ignore
  32. */
  33. protected $feedContainer;
  34. /**
  35. * Holds the XML document which is being generated.
  36. *
  37. * @var DOMDocument
  38. * @ignore
  39. */
  40. protected $xml;
  41. /**
  42. * Holds the root node of the XML document being generated.
  43. *
  44. * @var DOMNode
  45. * @ignore
  46. */
  47. protected $root;
  48. /**
  49. * Holds the channel element of the XML document being generated.
  50. *
  51. * @var DOMElement
  52. * @ignore
  53. */
  54. protected $channel;
  55. /**
  56. * Holds the prefixes used in the feed generation process.
  57. *
  58. * @var array(string)
  59. * @ignore
  60. */
  61. protected $usedPrefixes = array();
  62. /**
  63. * Sets the value of element $name to $value based on the feed schema.
  64. *
  65. * @param string $name The element name
  66. * @param mixed $value The new value for the element $name
  67. * @ignore
  68. */
  69. public function __set( $name, $value )
  70. {
  71. $this->feedContainer->$name = $value;
  72. }
  73. /**
  74. * Returns the value of element $name based on the feed schema.
  75. *
  76. * @param string $name The element name
  77. * @return mixed
  78. * @ignore
  79. */
  80. public function __get( $name )
  81. {
  82. return $this->feedContainer->$name;
  83. }
  84. /**
  85. * Returns if the property $name is set.
  86. *
  87. * @param string $name The property name
  88. * @return bool
  89. * @ignore
  90. */
  91. public function __isset( $name )
  92. {
  93. return isset( $this->feedContainer->$name );
  94. }
  95. /**
  96. * Returns an array with all the modules loaded at feed-level.
  97. *
  98. * @return array(ezcFeedModule)
  99. */
  100. public function getModules()
  101. {
  102. return $this->feedContainer->getModules();
  103. }
  104. /**
  105. * Creates a node in the XML document being generated with name $element
  106. * and value(s) $value.
  107. *
  108. * @param DOMNode $root The root in which to create the node $element
  109. * @param string $element The name of the XML element
  110. * @param mixed|array(mixed) $value The value(s) for $element
  111. * @ignore
  112. */
  113. protected function generateMetaData( DOMNode $root, $element, $value )
  114. {
  115. if ( !is_array( $value ) )
  116. {
  117. $value = array( $value );
  118. }
  119. foreach ( $value as $valueElement )
  120. {
  121. $meta = $this->xml->createElement( $element, ( $valueElement instanceof ezcFeedElement ) ? $valueElement->__toString() : (string)$valueElement );
  122. $root->appendChild( $meta );
  123. }
  124. }
  125. /**
  126. * Creates elements in the XML document being generated with name $element
  127. * and value(s) $value.
  128. *
  129. * @param DOMNode $root The root in which to create the node $element
  130. * @param string $element The name of the XML element
  131. * @param mixed|array(mixed) $value The value(s) for $element
  132. * @param array(string=>mixed) $attributes The attributes to add to the node
  133. * @ignore
  134. */
  135. protected function generateMetaDataWithAttributes( DOMNode $root, $element, $value = false, array $attributes )
  136. {
  137. if ( !is_array( $value ) )
  138. {
  139. $value = array( $value );
  140. }
  141. foreach ( $value as $valueElement )
  142. {
  143. if ( $valueElement === false )
  144. {
  145. $meta = $this->xml->createElement( $element );
  146. }
  147. else
  148. {
  149. $meta = $this->xml->createElement( $element, ( $valueElement instanceof ezcFeedElement ) ? $valueElement->__toString() : (string)$valueElement );
  150. }
  151. foreach ( $attributes as $attrName => $attrValue )
  152. {
  153. $attr = $this->xml->createAttribute( $attrName );
  154. $text = $this->xml->createTextNode( $attrValue );
  155. $attr->appendChild( $text );
  156. $meta->appendChild( $attr );
  157. }
  158. $root->appendChild( $meta );
  159. }
  160. }
  161. /**
  162. * Creates elements for all modules loaded at item-level, and adds the
  163. * namespaces required by the modules in the XML document being generated.
  164. *
  165. * @param ezcFeedEntryElement $item The feed item containing the modules
  166. * @param DOMElement $node The XML element in which to add the module elements
  167. * @ignore
  168. */
  169. protected function generateItemModules( ezcFeedEntryElement $item, DOMElement $node )
  170. {
  171. foreach ( $item->getModules() as $module )
  172. {
  173. $this->addAttribute( $this->root, 'xmlns:' . $module->getNamespacePrefix(), $module->getNamespace() );
  174. $module->generate( $this->xml, $node );
  175. }
  176. }
  177. /**
  178. * Creates elements for all modules loaded at feed-level, and adds the
  179. * namespaces required by the modules in the XML document being generated.
  180. *
  181. * @param DOMElement $node The XML element in which to add the module elements
  182. * @ignore
  183. */
  184. protected function generateFeedModules( DOMElement $node )
  185. {
  186. foreach ( $this->getModules() as $module )
  187. {
  188. $this->addAttribute( $this->root, 'xmlns:' . $module->getNamespacePrefix(), $module->getNamespace() );
  189. $module->generate( $this->xml, $node );
  190. }
  191. }
  192. /**
  193. * Parses the XML element $node and creates modules in the feed or
  194. * feed item $item.
  195. *
  196. * @param ezcFeedEntryElement|ezcFeed $item The feed or feed item which will contain the modules
  197. * @param DOMElement $node The XML element from which to get the module elements
  198. * @param string $tagName The XML tag name (if it contains ':' it will be considered part of a module)
  199. * @ignore
  200. */
  201. protected function parseModules( $item, DOMElement $node, $tagName )
  202. {
  203. $supportedModules = ezcFeed::getSupportedModules();
  204. if ( strpos( $tagName, ':' ) !== false )
  205. {
  206. list( $prefix, $key ) = explode( ':', $tagName );
  207. $moduleName = isset( $this->usedPrefixes[$prefix] ) ? $this->usedPrefixes[$prefix] : null;
  208. if ( isset( $supportedModules[$moduleName] ) )
  209. {
  210. $module = $item->hasModule( $moduleName ) ? $item->$moduleName : $item->addModule( $moduleName );
  211. $module->parse( $key, $node );
  212. }
  213. }
  214. }
  215. /**
  216. * Fetches the supported prefixes and namespaces from the XML document $xml.
  217. *
  218. * @param DOMDocument $xml The XML document object to parse
  219. * @return array(string=>string)
  220. * @ignore
  221. */
  222. protected function fetchUsedPrefixes( DOMDocument $xml )
  223. {
  224. $usedPrefixes = array();
  225. $xp = new DOMXpath( $xml );
  226. $set = $xp->query( './namespace::*', $xml->documentElement );
  227. $usedNamespaces = array();
  228. foreach ( $set as $node )
  229. {
  230. foreach ( ezcFeed::getSupportedModules() as $moduleName => $moduleClass )
  231. {
  232. $moduleNamespace = call_user_func( array( $moduleClass, 'getNamespace' ) );
  233. // compare the namespace URIs from the XML source with the supported ones
  234. if ( $moduleNamespace === $node->nodeValue )
  235. {
  236. // the nodeName looks like: xmlns:some_module
  237. list( $xmlns, $prefix ) = explode( ':', $node->nodeName );
  238. // use the prefix from the XML source as a key in the array $usedPrefixes
  239. // eg. array( 'some_prefix' => 'DublinCore' );
  240. // then, when calling later parseModules(), if encountering an element
  241. // like <some_prefix:creator>, it is checked if 'DublinCore' is supported
  242. $usedPrefixes[$prefix] = $moduleName;
  243. }
  244. }
  245. }
  246. return $usedPrefixes;
  247. }
  248. /**
  249. * Adds an attribute to the XML node $node.
  250. *
  251. * @param DOMNode $node The node to add the attribute to
  252. * @param string $attribute The name of the attribute to add
  253. * @param mixed $value The value of the attribute
  254. * @ignore
  255. */
  256. protected function addAttribute( DOMNode $node, $attribute, $value )
  257. {
  258. $attr = $this->xml->createAttribute( $attribute );
  259. $val = $this->xml->createTextNode( $value );
  260. $attr->appendChild( $val );
  261. $node->appendChild( $attr );
  262. }
  263. /**
  264. * Returns a DOMNode child of $parent with name $nodeName and which has an
  265. * attribute $attribute with the value $value. Returns null if no such node
  266. * is found.
  267. *
  268. * @param DOMNode $parent The XML parent node
  269. * @param string $nodeName The node name to find
  270. * @param string $attribute The attribute of the node
  271. * @param mixed $value The value of the attribute
  272. * @return DOMNode
  273. * @ignore
  274. */
  275. protected function getNodeByAttribute( DOMNode $parent, $nodeName, $attribute, $value )
  276. {
  277. $result = null;
  278. $nodes = $parent->getElementsByTagName( $nodeName );
  279. foreach ( $nodes as $node )
  280. {
  281. $nodeAttribute = $node->getAttribute( $attribute );
  282. if ( $nodeAttribute !== null
  283. && $nodeAttribute === $value )
  284. {
  285. $result = $node;
  286. break;
  287. }
  288. }
  289. return $result;
  290. }
  291. /**
  292. * Returns a DOMNode child of $parent with name $nodeName and which has an
  293. * attribute $attribute in the namespace $namespace with the value $value.
  294. * Returns null if no such node is found.
  295. *
  296. * @param DOMNode $parent The XML parent node
  297. * @param string $nodeName The node name to find
  298. * @param string $namespace The namespace of the attribute
  299. * @param string $attribute The attribute of the node
  300. * @param mixed $value The value of the attribute
  301. * @return DOMNode
  302. * @ignore
  303. */
  304. protected function getNodeByAttributeNS( DOMNode $parent, $nodeName, $namespace, $attribute, $value )
  305. {
  306. $result = null;
  307. $nodes = $parent->getElementsByTagName( $nodeName );
  308. foreach ( $nodes as $node )
  309. {
  310. $nodeAttribute = $node->getAttributeNS( $namespace, $attribute );
  311. if ( $nodeAttribute !== null
  312. && $nodeAttribute === $value )
  313. {
  314. $result = $node;
  315. break;
  316. }
  317. }
  318. return $result;
  319. }
  320. /**
  321. * Returns an XML string from the feed information contained in this
  322. * processor.
  323. *
  324. * @return string
  325. */
  326. abstract public function generate();
  327. }
  328. ?>