Newer
Older
maciej.zgadzaj
committed
<?php
/**
* @file
* Theme functions for Views RSS module.
*/
/**
maciej.zgadzaj
committed
* Template preprocessor for views-view-views-rss.tpl.php.
maciej.zgadzaj
committed
*/
function template_preprocess_views_view_views_rss(&$variables) {
$view = $variables['view'];
maciej.zgadzaj
committed
maciej.zgadzaj
committed
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// 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();
maciej.zgadzaj
committed
foreach (views_rss_get('channel_elements') as $module => $module_channel_elements) {
maciej.zgadzaj
committed
foreach ($module_channel_elements as $element => $definition) {
list($namespace, $element_name) = views_rss_extract_element_names($element, 'core');
maciej.zgadzaj
committed
// Try to fetch namespace value from view configuration.
maciej.zgadzaj
committed
if (isset($view->style_plugin->options['channel'][$namespace][$module][$element_name])) {
$value = $view->style_plugin->options['channel'][$namespace][$module][$element_name];
}
maciej.zgadzaj
committed
// Otherwise check if it was provided by element definition.
maciej.zgadzaj
committed
elseif (isset($definition['default_value'])) {
$value = $definition['default_value'];
}
else {
$value = NULL;
}
maciej.zgadzaj
committed
// 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);
maciej.zgadzaj
committed
// Start building XML channel element array compatible with format_xml_elements().
$rss_elements = array(
array(
'key' => $element,
'value' => $value,
),
);
maciej.zgadzaj
committed
// 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)) {
maciej.zgadzaj
committed
'elements' => &$rss_elements,
maciej.zgadzaj
committed
'item' => $view->style_plugin->options['channel'],
'view' => $view,
);
$preprocess_function($item_variables);
maciej.zgadzaj
committed
}
}
}
maciej.zgadzaj
committed
// 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.
maciej.zgadzaj
committed
foreach ($rss_elements as $key => $rss_element) {
if (empty($rss_element['value']) && empty($rss_element['attributes'])) {
unset($rss_elements[$key]);
}
maciej.zgadzaj
committed
}
maciej.zgadzaj
committed
if (empty($rss_elements)) continue;
// Add XML element(s) to the channel array.
$rss_channel = array_merge($rss_channel, $rss_elements);
maciej.zgadzaj
committed
}
}
maciej.zgadzaj
committed
// Channel array should not be added to the feed array yet, as first
// it needs to get populated with all <item> elements.
maciej.zgadzaj
committed
maciej.zgadzaj
committed
// Prepare <item> elements and add them to the channel array.
maciej.zgadzaj
committed
$item_elements = views_rss_get('item_elements');
$items = $view->style_plugin->map_rows($variables['rows']);
foreach ($items as $item_key => $item) {
maciej.zgadzaj
committed
// 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.
maciej.zgadzaj
committed
foreach (module_implements('views_rss_preprocess_item') as $module) {
$preprocess_function = $module . '_views_rss_preprocess_item';
$item_variables = array(
maciej.zgadzaj
committed
'item' => &$item,
maciej.zgadzaj
committed
'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);
maciej.zgadzaj
committed
}
maciej.zgadzaj
committed
// Process each element separately.
maciej.zgadzaj
committed
foreach ($item as $module => $module_item_elements) {
foreach ($module_item_elements as $element => $value) {
maciej.zgadzaj
committed
// 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);
}
maciej.zgadzaj
committed
// Start building XML element array compatible with format_xml_elements().
$rss_elements = array(
array(
'key' => $element,
'value' => $value,
),
);
maciej.zgadzaj
committed
// 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)) {
maciej.zgadzaj
committed
'elements' => &$rss_elements,
maciej.zgadzaj
committed
);
// 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];
maciej.zgadzaj
committed
}
}
}
// If no preprocess function was defined, and we have received
maciej.zgadzaj
committed
// #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) {
maciej.zgadzaj
committed
if (!empty($raw_item['rendered']['#rss_element'])) {
$formatter_rss_elements[] = $raw_item['rendered']['#rss_element'];
}
}
maciej.zgadzaj
committed
// Now we can overwrite main $rss_elements.
if (!empty($formatter_rss_elements)) {
$rss_elements = $formatter_rss_elements;
}
}
maciej.zgadzaj
committed
// 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.
maciej.zgadzaj
committed
foreach ($rss_elements as $key => $rss_element) {
if (empty($rss_element['value']) && empty($rss_element['attributes'])) {
unset($rss_elements[$key]);
}
maciej.zgadzaj
committed
}
maciej.zgadzaj
committed
if (empty($rss_elements)) continue;
maciej.zgadzaj
committed
maciej.zgadzaj
committed
// Add XML element(s) to the item array.
$rss_item['value'] = array_merge($rss_item['value'], $rss_elements);
maciej.zgadzaj
committed
}
}
maciej.zgadzaj
committed
// Add XML item element to the channe; array.
$rss_channel[] = $rss_item;
maciej.zgadzaj
committed
}
maciej.zgadzaj
committed
// Finally, let's put together the whole feed array.
$rss_feed['value'][] = array(
'key' => 'channel',
'value' => $rss_channel,
);
maciej.zgadzaj
committed
maciej.zgadzaj
committed
// Allow for altering it before final render and passing it to the template.
drupal_alter('views_rss_feed', $rss_feed);
maciej.zgadzaj
committed
maciej.zgadzaj
committed
// 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');