123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- <?php
- /**
- * @file
- * Theme functions for Views RSS module.
- */
- /**
- * Template preprocessor for views-view-views-rss.tpl.php.
- */
- function template_preprocess_views_view_views_rss(&$variables) {
- $view = $variables['view'];
- // Start building the feed array compatible with format_xml_elements().
- $rss_feed = array(
- 'key' => 'rss',
- 'attributes' => array(
- 'version' => '2.0',
- ),
- 'value' => array(),
- );
- // Prepare namespaces and add them to feed array.
- // xml:base cannot be defined by hook_views_rss_namespaces() implementation,
- // as we don't want its value to be cached, it needs to be dynamic.
- $rss_feed['attributes']['xml:base'] = url('<front>', array('absolute' => TRUE));
- // All other namespaces are taken from hook_views_rss_namespaces() implementations.
- foreach (views_rss_get('namespaces') as $module => $module_namespaces) {
- foreach ($module_namespaces as $namespace => $definition) {
- // Check if definition provided through modules hooks
- // should be overwritten by module configuration.
- if (
- isset($view->style_plugin->options['namespaces'][$module][$namespace])
- && !empty($view->style_plugin->options['namespaces'][$module][$namespace])
- ) {
- $definition['uri'] = $view->style_plugin->options['namespaces'][$module][$namespace];
- }
- // Add namespace to feed array.
- if (isset($definition['uri']) && !empty($definition['uri'])) {
- // Namespaces with prefix, for example xml:base="" or xmlns:dc=""
- if (isset($definition['prefix']) && !empty($definition['prefix'])) {
- $namespace_key = $definition['prefix'] . ':' . $namespace;
- $rss_feed['attributes'][$namespace_key] = $definition['uri'];
- }
- // Namespaces without prefix, for example: content="" or foaf=""
- else {
- $rss_feed['attributes'][$namespace] = $definition['uri'];
- }
- }
- }
- }
- // Prepare <channel> elements and add them to feed array.
- $rss_channel = array();
- foreach (views_rss_get('channel_elements') as $module => $module_channel_elements) {
- foreach ($module_channel_elements as $element => $definition) {
- list($namespace, $element_name) = views_rss_extract_element_names($element, 'core');
- // Try to fetch namespace value from view configuration.
- if (isset($view->style_plugin->options['channel'][$namespace][$module][$element_name])) {
- $value = $view->style_plugin->options['channel'][$namespace][$module][$element_name];
- }
- // Otherwise check if it was provided by element definition.
- elseif (isset($definition['default_value'])) {
- $value = $definition['default_value'];
- }
- else {
- $value = NULL;
- }
- // Avoid double encoding: the $value might be already encoded here,
- // depending on the field configuration/processing, and because we know
- // it will be encoded again when the whole feed array will be passed to
- // format_xml_elements(), let's make sure we decode it here first.
- if (is_string($value)) {
- $value = decode_entities($value);
- }
- // Start building XML channel element array compatible with format_xml_elements().
- $rss_elements = array(
- array(
- 'key' => $element,
- 'value' => $value,
- ),
- );
- // Preprocess element value.
- if (isset($definition['preprocess functions']) && is_array($definition['preprocess functions'])) {
- foreach ($definition['preprocess functions'] as $preprocess_function) {
- if (function_exists($preprocess_function)) {
- $item_variables = array(
- 'elements' => &$rss_elements,
- 'item' => $view->style_plugin->options['channel'],
- 'view' => $view,
- );
- $preprocess_function($item_variables);
- }
- }
- }
- // If there is no value and no attributes (in case of self-closing elements)
- // already set for the element at this stage, it is not going to be set
- // at any point further, so the element should not be added to the feed.
- foreach ($rss_elements as $key => $rss_element) {
- if (empty($rss_element['value']) && empty($rss_element['attributes'])) {
- unset($rss_elements[$key]);
- }
- }
- if (empty($rss_elements)) continue;
- // Add XML element(s) to the channel array.
- $rss_channel = array_merge($rss_channel, $rss_elements);
- }
- }
- // Channel array should not be added to the feed array yet, as first
- // it needs to get populated with all <item> elements.
- // Prepare <item> elements and add them to the channel array.
- $item_elements = views_rss_get('item_elements');
- $items = $view->style_plugin->map_rows($variables['rows']);
- foreach ($items as $item_key => $item) {
- // Start building XML item element array compatible with format_xml_elements().
- $rss_item = array(
- 'key' => 'item',
- 'value' => array(),
- );
- // Preprocess whole item array before preprocessing separate elements.
- foreach (module_implements('views_rss_preprocess_item') as $module) {
- $preprocess_function = $module . '_views_rss_preprocess_item';
- $item_variables = array(
- 'item' => &$item,
- 'view' => $view,
- );
- // Add raw row if generated based on raw item values provided by field formatter.
- if (!empty($view->views_rss['raw_items'][$item_key])) {
- $item_variables['raw'] = $view->views_rss['raw_items'][$item_key];
- }
- $preprocess_function($item_variables);
- }
- // Process each element separately.
- foreach ($item as $module => $module_item_elements) {
- foreach ($module_item_elements as $element => $value) {
- // Avoid double encoding: the $value might be already encoded here,
- // depending on the field configuration/processing, and because we know
- // it will be encoded again when the whole feed array will be passed to
- // format_xml_elements(), let's make sure we decode it here first.
- if (is_string($value)) {
- $value = decode_entities($value);
- }
- // Start building XML element array compatible with format_xml_elements().
- $rss_elements = array(
- array(
- 'key' => $element,
- 'value' => $value,
- ),
- );
- // Preprocess element initial value if required.
- if (isset($item_elements[$module][$element]['preprocess functions']) && is_array($item_elements[$module][$element]['preprocess functions'])) {
- foreach ($item_elements[$module][$element]['preprocess functions'] as $preprocess_function) {
- if (function_exists($preprocess_function)) {
- $item_variables = array(
- 'elements' => &$rss_elements,
- 'item' => $item,
- 'view' => $view,
- );
- // Add raw item if provided by field formatter.
- if (!empty($view->views_rss['raw_items'][$item_key][$module][$element])) {
- $item_variables['raw'] = $view->views_rss['raw_items'][$item_key][$module][$element];
- }
- $preprocess_function($item_variables);
- }
- }
- }
- // If no preprocess function was defined, and we have received
- // #rss_element value (XML element array) from the formatter, it should
- // be added to the feed array without any further modifications.
- elseif (
- !empty($view->views_rss['raw_items'][$item_key][$module][$element])
- && is_array($view->views_rss['raw_items'][$item_key][$module][$element])
- ) {
- // At this point we don't know yet if we got #rss_elements in raw
- // values, so do not overwrite and empty main $rss_elements yet, just
- // start working with new $formatter_rss_elements - it could be
- // overwritten once we are sure we have all required values.
- $formatter_rss_elements = array();
- foreach ($view->views_rss['raw_items'][$item_key][$module][$element] as $raw_item) {
- if (!empty($raw_item['rendered']['#rss_element'])) {
- $formatter_rss_elements[] = $raw_item['rendered']['#rss_element'];
- }
- }
- // Now we can overwrite main $rss_elements.
- if (!empty($formatter_rss_elements)) {
- $rss_elements = $formatter_rss_elements;
- }
- }
- // If there is no value and no attributes (in case of self-closing elements)
- // already set for the element at this stage, it is not going to be set
- // at any point further, so the element should not be added to the feed.
- foreach ($rss_elements as $key => $rss_element) {
- if (empty($rss_element['value']) && empty($rss_element['attributes'])) {
- unset($rss_elements[$key]);
- }
- }
- if (empty($rss_elements)) continue;
- // Add XML element(s) to the item array.
- $rss_item['value'] = array_merge($rss_item['value'], $rss_elements);
- }
- }
- // Add XML item element to the channe; array.
- $rss_channel[] = $rss_item;
- }
- // Finally, let's put together the whole feed array.
- $rss_feed['value'][] = array(
- 'key' => 'channel',
- 'value' => $rss_channel,
- );
- // Allow for altering it before final render and passing it to the template.
- drupal_alter('views_rss_feed', $rss_feed);
- // Assign rendered feed to the template variables.
- $variables['rss_feed'] = format_xml_elements(array($rss_feed));
- // Set XML header.
- drupal_add_http_header('Content-Type', 'application/rss+xml; charset=utf-8');
- }
|