theme.inc 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <?php
  2. /**
  3. * @file
  4. * Theme functions for Views RSS module.
  5. */
  6. /**
  7. * Template preprocessor for views-view-views-rss.tpl.php.
  8. */
  9. function template_preprocess_views_view_views_rss(&$variables) {
  10. $view = $variables['view'];
  11. // Start building the feed array compatible with format_xml_elements().
  12. $rss_feed = array(
  13. 'key' => 'rss',
  14. 'attributes' => array(
  15. 'version' => '2.0',
  16. ),
  17. 'value' => array(),
  18. );
  19. // Prepare namespaces and add them to feed array.
  20. // xml:base cannot be defined by hook_views_rss_namespaces() implementation,
  21. // as we don't want its value to be cached, it needs to be dynamic.
  22. $rss_feed['attributes']['xml:base'] = url('<front>', array('absolute' => TRUE));
  23. // All other namespaces are taken from hook_views_rss_namespaces() implementations.
  24. foreach (views_rss_get('namespaces') as $module => $module_namespaces) {
  25. foreach ($module_namespaces as $namespace => $definition) {
  26. // Check if definition provided through modules hooks
  27. // should be overwritten by module configuration.
  28. if (
  29. isset($view->style_plugin->options['namespaces'][$module][$namespace])
  30. && !empty($view->style_plugin->options['namespaces'][$module][$namespace])
  31. ) {
  32. $definition['uri'] = $view->style_plugin->options['namespaces'][$module][$namespace];
  33. }
  34. // Add namespace to feed array.
  35. if (isset($definition['uri']) && !empty($definition['uri'])) {
  36. // Namespaces with prefix, for example xml:base="" or xmlns:dc=""
  37. if (isset($definition['prefix']) && !empty($definition['prefix'])) {
  38. $namespace_key = $definition['prefix'] . ':' . $namespace;
  39. $rss_feed['attributes'][$namespace_key] = $definition['uri'];
  40. }
  41. // Namespaces without prefix, for example: content="" or foaf=""
  42. else {
  43. $rss_feed['attributes'][$namespace] = $definition['uri'];
  44. }
  45. }
  46. }
  47. }
  48. // Prepare <channel> elements and add them to feed array.
  49. $rss_channel = array();
  50. foreach (views_rss_get('channel_elements') as $module => $module_channel_elements) {
  51. foreach ($module_channel_elements as $element => $definition) {
  52. list($namespace, $element_name) = views_rss_extract_element_names($element, 'core');
  53. // Try to fetch namespace value from view configuration.
  54. if (isset($view->style_plugin->options['channel'][$namespace][$module][$element_name])) {
  55. $value = $view->style_plugin->options['channel'][$namespace][$module][$element_name];
  56. }
  57. // Otherwise check if it was provided by element definition.
  58. elseif (isset($definition['default_value'])) {
  59. $value = $definition['default_value'];
  60. }
  61. else {
  62. $value = NULL;
  63. }
  64. // Start building XML channel element array compatible with format_xml_elements().
  65. $rss_elements = array(
  66. array(
  67. 'key' => $element,
  68. 'value' => $value,
  69. ),
  70. );
  71. // Preprocess element value.
  72. if (isset($definition['preprocess functions']) && is_array($definition['preprocess functions'])) {
  73. foreach ($definition['preprocess functions'] as $preprocess_function) {
  74. if (function_exists($preprocess_function)) {
  75. $item_variables = array(
  76. 'elements' => &$rss_elements,
  77. 'item' => $view->style_plugin->options['channel'],
  78. 'view' => $view,
  79. );
  80. $preprocess_function($item_variables);
  81. }
  82. }
  83. }
  84. // If there is no value and no attributes (in case of self-closing elements)
  85. // already set for the element at this stage, it is not going to be set
  86. // at any point further, so the element should not be added to the feed.
  87. foreach ($rss_elements as $key => $rss_element) {
  88. if (empty($rss_element['value']) && empty($rss_element['attributes'])) {
  89. unset($rss_elements[$key]);
  90. }
  91. }
  92. if (empty($rss_elements)) continue;
  93. // Add XML element(s) to the channel array.
  94. $rss_channel = array_merge($rss_channel, $rss_elements);
  95. }
  96. }
  97. // Channel array should not be added to the feed array yet, as first
  98. // it needs to get populated with all <item> elements.
  99. // Prepare <item> elements and add them to the channel array.
  100. $item_elements = views_rss_get('item_elements');
  101. $items = $view->style_plugin->map_rows($variables['rows']);
  102. foreach ($items as $item_key => $item) {
  103. // Start building XML item element array compatible with format_xml_elements().
  104. $rss_item = array(
  105. 'key' => 'item',
  106. 'value' => array(),
  107. );
  108. // Preprocess whole item array before preprocessing separate elements.
  109. foreach (module_implements('views_rss_preprocess_item') as $module) {
  110. $preprocess_function = $module . '_views_rss_preprocess_item';
  111. $item_variables = array(
  112. 'item' => &$item,
  113. 'view' => $view,
  114. );
  115. // Add raw row if generated based on raw item values provided by field formatter.
  116. if (!empty($view->views_rss['raw_items'][$item_key])) {
  117. $item_variables['raw'] = $view->views_rss['raw_items'][$item_key];
  118. }
  119. $preprocess_function($item_variables);
  120. }
  121. // Process each element separately.
  122. foreach ($item as $module => $module_item_elements) {
  123. foreach ($module_item_elements as $element => $value) {
  124. // Start building XML element array compatible with format_xml_elements().
  125. $rss_elements = array(
  126. array(
  127. 'key' => $element,
  128. 'value' => $value,
  129. ),
  130. );
  131. // Preprocess element initial value if required.
  132. if (isset($item_elements[$module][$element]['preprocess functions']) && is_array($item_elements[$module][$element]['preprocess functions'])) {
  133. foreach ($item_elements[$module][$element]['preprocess functions'] as $preprocess_function) {
  134. if (function_exists($preprocess_function)) {
  135. $item_variables = array(
  136. 'elements' => &$rss_elements,
  137. 'item' => $item,
  138. 'view' => $view,
  139. );
  140. // Add raw item if provided by field formatter.
  141. if (!empty($view->views_rss['raw_items'][$item_key][$module][$element])) {
  142. $item_variables['raw'] = $view->views_rss['raw_items'][$item_key][$module][$element];
  143. }
  144. $preprocess_function($item_variables);
  145. }
  146. }
  147. }
  148. // If no preprocess function was defined, and we have received
  149. // #rss_element value (XML element array) from the formatter, it should
  150. // be added to the feed array without any further modifications.
  151. elseif (
  152. !empty($view->views_rss['raw_items'][$item_key][$module][$element])
  153. && is_array($view->views_rss['raw_items'][$item_key][$module][$element])
  154. ) {
  155. // At this point we don't know yet if we got #rss_elements in raw
  156. // values, so do not overwrite and empty main $rss_elements yet, just
  157. // start working with new $formatter_rss_elements - it could be
  158. // overwritten once we are sure we have all required values.
  159. $formatter_rss_elements = array();
  160. foreach ($view->views_rss['raw_items'][$item_key][$module][$element] as $raw_item) {
  161. if (!empty($raw_item['rendered']['#rss_element'])) {
  162. $formatter_rss_elements[] = $raw_item['rendered']['#rss_element'];
  163. }
  164. }
  165. // Now we can overwrite main $rss_elements.
  166. if (!empty($formatter_rss_elements)) {
  167. $rss_elements = $formatter_rss_elements;
  168. }
  169. }
  170. // If there is no value and no attributes (in case of self-closing elements)
  171. // already set for the element at this stage, it is not going to be set
  172. // at any point further, so the element should not be added to the feed.
  173. foreach ($rss_elements as $key => $rss_element) {
  174. if (empty($rss_element['value']) && empty($rss_element['attributes'])) {
  175. unset($rss_elements[$key]);
  176. }
  177. }
  178. if (empty($rss_elements)) continue;
  179. // Add XML element(s) to the item array.
  180. $rss_item['value'] = array_merge($rss_item['value'], $rss_elements);
  181. }
  182. }
  183. // Add XML item element to the channe; array.
  184. $rss_channel[] = $rss_item;
  185. }
  186. // Finally, let's put together the whole feed array.
  187. $rss_feed['value'][] = array(
  188. 'key' => 'channel',
  189. 'value' => $rss_channel,
  190. );
  191. // Allow for altering it before final render and passing it to the template.
  192. drupal_alter('views_rss_feed', $rss_feed);
  193. // Assign rendered feed to the template variables.
  194. $variables['rss_feed'] = format_xml_elements(array($rss_feed));
  195. // Set XML header.
  196. drupal_add_http_header('Content-Type', 'application/rss+xml; charset=utf-8');
  197. }